tutorial google gae flexible example engine app google-app-engine java

gae - Google app engine JRE Class "Black List"



google app engine java 9 (5)

Hay una " Lista blanca de la clase JRE " para Google App Engine.

Lo que realmente me gustaría es una "Lista negra", es decir, API de Java que no funcionarán en GAE. ¿Existe tal lista? ¿Algún desarrollador ha tenido problemas con las API de Java en GAE?


Estaba buscando algo cuando me encontré con esta consulta y pensé en compartir los detalles en la lista en blanco y negro de GAE (Google App Engine) para que cualquier persona que tenga ese problema pueda abordarlo correctamente. Detalles:

appengine-agentruntime.jar tiene dos variables de instancia como: -

private static Agent agent private static Set<String> blackList

Estamos obteniendo blackList de agent & agent = AppEngineDevAgent.getAgent() . Entonces, si revisamos b) appengine-agent.jar , podemos encontrar que el agente es Class<?> implClass = agentImplLoader.loadClass("com.google.appengine.tools.development.agent.impl.AgentImpl");

Y luego ir a la clase AgentImpl, es decir, c) appengine-agentimpl.jar , podemos ver que la variable de la lista negra se rellena en la carga de la clase con la inicialización estática y remite la Lista blanca para filtrar las clases permitidas.

static { initBlackList(); } public static Set<String> getBlackList() { return blackList; } private static boolean isBlackListed(String className) { Set<String> whiteList = WhiteList.getWhiteList(); return (!whiteList.contains(className)) && (!className.startsWith("com.sun.xml.internal.bind.")); }

Finalmente puede verificar d) appengine-tools-sdk-1.8.3.jar para obtener una lista de todas las clases de WhiteList.

Conclusión: como un truco para utilizar cualquier clase JRE que no pertenezca a esta WhiteList, es necesario jugar con la WhiteList o con la BlackList . Un posible truco sería si deshace la biblioteca appengine-agentruntime.jar y comenta el contenido del método de rechazo como

public static void reject(String className) { /*throw new NoClassDefFoundError(className + " is a restricted class. Please see the Google " + " App Engine developer''s guide for more details.");*/ }

Y luego jar y usar en su proyecto. Espero que ayude.

-------------------------------------------------- ---------------------------

a) appengine-agentruntime.jar : - Tiene la clase Runtime real que arroja una excepción (del método de rechazo ) para las clases que no pertenecen a la lista blanca anterior.

package com.google.appengine.tools.development.agent.runtime; import com.google.appengine.tools.development.agent.AppEngineDevAgent; import com.google.appengine.tools.development.agent.impl.Agent; import com.google.apphosting.utils.clearcast.ClearCast; //REMOVED OTHER IMPORTS TO KEEP IT SHORT public class Runtime { private static Agent agent = (Agent) ClearCast.cast( AppEngineDevAgent.getAgent(), Agent.class); private static Set<String> blackList = agent.getBlackList(); public static ClassLoader checkParentClassLoader(ClassLoader loader) { ClassLoader systemLoader = ClassLoader.getSystemClassLoader(); return (loader != null) && (loader != systemLoader) ? loader : Runtime.class.getClassLoader(); } public static void recordClassLoader(ClassLoader loader) { agent.recordAppClassLoader(loader); } public static void reject(String className) { throw new NoClassDefFoundError(className + " is a restricted class. Please see the Google " + " App Engine developer''s guide for more details."); } private static boolean isBlackListed(Class klass) { String className = klass.getName().replace(''.'', ''/''); return blackList.contains(className); } // REMOVED OTHER METHODS TO KEEP IT SHORT }

b) appengine-agent.jar : -

package com.google.appengine.tools.development.agent; import com.google.apphosting.utils.clearcast.ClearCast; //REMOVED OTHER IMPORTS TO KEEP IT SHORT public class AppEngineDevAgent { private static final String AGENT_IMPL = "com.google.appengine.tools.development.agent.impl.AgentImpl"; private static final String AGENT_IMPL_JAR = "appengine-agentimpl.jar"; private static final Logger logger = Logger.getLogger(AppEngineDevAgent.class.getName()); private static Object impl; public static void premain(String agentArgs, Instrumentation inst) { URL agentImplLib = findAgentImplLib(); URLClassLoader agentImplLoader = new URLClassLoader( new URL[] { agentImplLib }) { protected PermissionCollection getPermissions(CodeSource codesource) { PermissionCollection perms = super.getPermissions(codesource); perms.add(new AllPermission()); return perms; } }; try { Class<?> implClass = agentImplLoader .loadClass("com.google.appengine.tools.development.agent.impl.AgentImpl"); impl = ((AgentImplStruct) ClearCast.staticCast(implClass, AgentImplStruct.class)).getInstance(); AgentImplStruct agentImplStruct = (AgentImplStruct) ClearCast.cast( impl, AgentImplStruct.class); agentImplStruct.run(inst); } catch (Exception e) { logger.log( Level.SEVERE, "Unable to load the App Engine dev agent. Security restrictions will not be completely emulated.", e); } } public static Object getAgent() { return impl; } //REMOVED OTHER METHODS TO KEEP IT SHORT }

c) appengine-agentimpl.jar : -

package com.google.appengine.tools.development.agent.impl; import com.google.apphosting.runtime.security.WhiteList; //REMOVED OTHER IMPORTS TO KEEP IT SHORT public class BlackList { private static final Logger logger = Logger.getLogger(BlackList.class.getName()); private static Set<String> blackList = new HashSet(); static { initBlackList(); } public static Set<String> getBlackList() { return blackList; } private static boolean isBlackListed(String className) { Set<String> whiteList = WhiteList.getWhiteList(); return (!whiteList.contains(className)) && (!className.startsWith("com.sun.xml.internal.bind.")); } private static void initBlackList() { Set<File> jreJars = getCurrentJreJars(); for (File f : jreJars) { JarFile jarFile = null; try { jarFile = new JarFile(f); } catch (IOException e) { logger.log( Level.SEVERE, "Unable to read a jre library while constructing the blacklist. Security restrictions may not be entirely emulated. " + f.getAbsolutePath()); } continue; Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = (JarEntry) entries.nextElement(); String entryName = entry.getName(); if (entryName.endsWith(".class")) { String className = entryName.replace(''/'', ''.'').substring(0, entryName.length() - ".class".length()); if (isBlackListed(className)) { blackList.add(className.replace(''.'', ''/'')); } } } } blackList = Collections.unmodifiableSet(blackList); } private static Set<File> getCurrentJreJars() { return getJreJars(System.getProperty("java.home")); } //REMOVED OTHER METHODS TO KEEP IT SHORT }

d) appengine-tools-sdk-1.8.3.jar : - Tiene una clase llamada WhiteList que incluye todas las clases de JRE permitidas.

package com.google.apphosting.runtime.security; import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class WhiteList { private static Set<String> whiteList = new HashSet( Arrays.asList(new String[] { "java.beans.Transient", "java.lang.BootstrapMethodError", "java.lang.Character$UnicodeScript", "java.lang.ClassValue", "java.lang.SafeVarargs", //Removed other classes to keep this article short "java.net.URLClassLoader", "java.security.SecureClassLoader", "sun.net.spi.nameservice.NameService" })); public static Set<String> getWhiteList() { return whiteList; } }





Yo uso Servlet en mi proyecto GAE, sin embargo, no está en la lista blanca, incluso cuando funcionará sin ningún problema. De hecho, Google menciona cómo usar Servlet pero no está en la lista blanca

import javax.servlet.http. *;

Mencionado aquí:

http://code.google.com/appengine/docs/java/runtime.html

pero no incluido aquí:

http://code.google.com/appengine/docs/java/jrewhitelist.html

Me encanta GAE (porque la cuota libre) pero la documentación es un desastre.

Yo uso IntelliJ y marca como un error cuando la importación no está en la lista blanca. Sin embargo, es posible desactivarlo.