最近 看到 appgeng 被封了。。开始担心起自己的应用了。
使用 google 的appengine 进行开发的时候的成都在 而且 appeng 运行速度 还比tomcat 跑的快些
google 没有给出 在本地 如何集群 如何 连接 数据库的 方案。
我想应该从 appeng 白名单开始。google的白名单包括了一些java 中用到的类。
我想在本地 的环境下面运行这些类。。服务器上面就肯定不行了。。那个google说了算。
首先修改下白名单
package com.google.apphosting.runtime.security; import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.commons.io.FileUtils; public class GenWhiteListMain { public static void main(String args[]) throws IOException { JarFile jarFile = new JarFile("/opt/jdk/jdk1.6/jre/lib/rt.jar"); Enumeration enum1 = jarFile.entries(); StringBuffer buffer = new StringBuffer(); while (enum1.hasMoreElements()) { JarEntry entry = (JarEntry) enum1.nextElement(); String name = entry.getName(); name = name.replace("/", "."); if (name.indexOf("com.sun") >= 0) { continue; } if (name.indexOf("sun.") == 0) { continue; } if (name.indexOf("com.sun") >= 0) { continue; } if (name.indexOf("javax.swing") >= 0) { continue; } if (name.indexOf("org.omg") >= 0) { continue; } if (name.indexOf("org.ietf") >= 0) { continue; } if (name.indexOf(".class") >= 0) { name = name.replace(".class", ""); // System.out.println("\"" + name + "\","); buffer.append("\"" + name + "\",\n"); } } System.out.println("finish"); FileUtils.writeStringToFile(new File("src/WhiteList.txt"), buffer.toString()); } }
读取jar 文件里面的所有文件 并去除一些 不常用户的。
然后修改将白名单修改
(这里就不贴了。好几千行的东西。)
然后发现运行的时候需要 重启 eclipse 否则编译报错。
然后运行 google appeng 还是报不能访问 继续修改一个类
package com.google.appengine.tools.development; import com.google.apphosting.utils.security.SecurityManagerInstaller; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.security.Permission; import java.security.Permissions; import java.util.PropertyPermission; public class DevAppServerFactory { static final String DEV_APP_SERVER_CLASS = "com.google.appengine.tools.development.DevAppServerImpl"; public DevAppServer createDevAppServer(File appLocation, String address, int port) { return createDevAppServer(new Class[] { File.class, String.class, Integer.TYPE }, new Object[] { appLocation, address, Integer.valueOf(port) }); } private DevAppServer createDevAppServer(File appLocation, String appEngineWebXml, String address, int port, boolean useCustomStreamHandler) { return createDevAppServer( new Class[] { File.class, String.class, String.class, String.class, Integer.TYPE, Boolean.TYPE }, new Object[] { appLocation, null, appEngineWebXml, address, Integer.valueOf(port), Boolean.valueOf(useCustomStreamHandler) }); } private DevAppServer createDevAppServer(Class[] ctorArgTypes, Object[] ctorArgs) { SecurityManagerInstaller.install(new URL[0]); DevAppServerClassLoader loader = DevAppServerClassLoader .newClassLoader(DevAppServerFactory.class.getClassLoader()); testAgentIsInstalled(); DevAppServer devAppServer; try { Class devAppServerClass = Class.forName( "com.google.appengine.tools.development.DevAppServerImpl", true, loader); Constructor cons = devAppServerClass.getConstructor(ctorArgTypes); cons.setAccessible(true); devAppServer = (DevAppServer) cons.newInstance(ctorArgs); } catch (Exception e) { Throwable t = e; if (e instanceof InvocationTargetException) { t = e.getCause(); } throw new RuntimeException("Unable to create a DevAppServer", t); } System.setSecurityManager(new CustomSecurityManager(devAppServer)); return devAppServer; } private void testAgentIsInstalled() { try { // AppEngineDevAgent.getAgent(); } catch (Throwable t) { String msg = "Unable to locate the App Engine agent. Please use dev_appserver, KickStart, or set the jvm flag: \"-javaagent:<sdk_root>/lib/agent/appengine-agent.jar\""; throw new RuntimeException(msg, t); } } private static class CustomSecurityManager extends SecurityManager { private static final RuntimePermission PERMISSION_MODIFY_THREAD_GROUP = new RuntimePermission( "modifyThreadGroup"); private static final RuntimePermission PERMISSION_MODIFY_THREAD = new RuntimePermission( "modifyThread"); private static final String KEYCHAIN_JNILIB = "/libkeychain.jnilib"; private static final Object PERMISSION_LOCK = new Object(); private final DevAppServer devAppServer; public CustomSecurityManager(DevAppServer devAppServer) { this.devAppServer = devAppServer; } private synchronized boolean appHasPermission(Permission perm) { return true; /** 直接返回 */ } public void checkPermission(Permission perm) { if (true) { return; /** 直接返回 */ } } public void checkPermission(Permission perm, Object context) { if (true) { return; /** 直接返回 */ } } public void checkAccess(ThreadGroup g) { if (true) { return; /** 直接返回 */ } } public void checkAccess(Thread t) { if (true) { return; /** 直接返回 */ } } public boolean isDevAppServerThread() { // return Boolean.getBoolean("devappserver-thread-" // + Thread.currentThread().getName()); return true; } } }
将一些判断直接 返回。
然后继续重启 eclispe 发现可以写文件 运行 线程了。。
测试servletpackage com.test;
import java.io.File; import java.io.IOException; import java.net.Socket; import javax.servlet.http.*; import org.apache.commons.io.FileUtils; @SuppressWarnings("serial") public class TestWhiteServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/plain"); FileUtils.writeStringToFile(new File("/tmp/app.write.txt"), "1234"); TestThread thread = new TestThread(); thread.start(); resp.getWriter().println("Hello, world"); } }
一个写文件一个创建线程。没有报错。
附件
testWhiteList_src.tar.gz
是我自己源文件。
appengine-tools-api.jar 是替换后的文件
放到 appengine-sdk/lib 目录下面替换
想着是 如果 老是上不去 app服务器。可以自己本地跑程序了。自己写点线程。
上传照片的时候可以直接传到 自己的服务器上了。
这样 appengine 就和一个 tomcat 一样了。不过带一个 文件数据库。
但appengine 有一些配置挺方便的如:
<static-files> <include path="/**.png" expiration="4d 5h" /> </static-files>
缓存图片
http://code.google.com/appengine/docs/java/config/appconfig.html
接下来研究 appengine 本地集群 性能如何。我想应该有这些配置。只不过 文档没说。