将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 本地集群 性能如何。我想应该有这些配置。只不过 文档没说。

上一篇:蜗牛爬行日记——正则表达式与第一个爬虫程序


下一篇:关于ncnn的运行环境安装