最近 看到 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");
}
}
一个写文件一个创建线程。没有报错。
附件
是我自己源文件。
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 本地集群 性能如何。我想应该有这些配置。只不过 文档没说。