将google app engine 进行 本地化 可写文件 创建线程 去除白名单
?最近 看到 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 本地集群 性能如何。我想应该有这些配置。只不过 文档没说。