Gson auf Google App Engine führt eine Sicherheitsausnahme
-
25-09-2019 - |
Frage
Ich versuche, ein Objekt in JSON mit der Gson Bibliothek auf Google App Engine zu konvertieren. Aus irgendeinem Grund, wirft sie diese Ausnahme und ich verstehe nicht, wie diese zu lösen. Irgendwelche Vorschläge?
java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private static final int java.util.BitSet.ADDRESS_BITS_PER_WORD
at com.google.appengine.runtime.Request.process-8d5b435d6736643f(Request.java)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:29)
at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:141)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123)
at com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:148)
at com.google.gson.JsonSerializationVisitor.addAsArrayElement(JsonSerializationVisitor.java:139)
at com.google.gson.JsonSerializationVisitor.visitArray(JsonSerializationVisitor.java:83)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:109)
at com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:148)
at com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVisitor.java:126)
at com.google.gson.JsonSerializationVisitor.visitArrayField(JsonSerializationVisitor.java:95)
at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:154)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123)
at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:56)
at com.google.gson.Gson.toJsonTree(Gson.java:230)
at com.google.gson.Gson.toJson(Gson.java:315)
at com.google.gson.Gson.toJson(Gson.java:270)
at com.google.gson.Gson.toJson(Gson.java:250)
at companionmodel.Sample_Model_PopulateServlet.printOutput(Sample_Model_PopulateServlet.java:59)
at companionmodel.Sample_Model_PopulateServlet.doGet(Sample_Model_PopulateServlet.java:28)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:693)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:97)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:238)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:135)
at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:250)
at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5838)
at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5836)
at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:398)
at com.google.net.rpc.impl.Server$2.run(Server.java:852)
at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:576)
at com.google.net.rpc.impl.Server.startRpc(Server.java:807)
at com.google.net.rpc.impl.Server.processRequest(Server.java:369)
at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:442)
at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)
at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)
at com.google.net.async.Connection.handleReadEvent(Connection.java:474)
at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:831)
at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:103)
at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:413)
at java.lang.Thread.run(Unknown Source)
-Code Ich bin mit:
Gson gson = new Gson();
String json = gson.toJson(modelObject);
Lösung
Die App Engine unterstützt jedoch reflection - aber Sie versuchen, auf einem privaten Feld einer JRE Klasse widerzuspiegeln:
Reflexion
Eine Anwendung ist erlaubt voll, uneingeschränkter, reflektierendes Zugang zu seinem eigene Klassen. Es kann jedes private abfragen Mitglieder, die Verwendung java.lang.reflect.AccessibleObject.setAccessible (), und lesen / set private Mitglieder.
Eine Anwendung kann auch auch reflektieren auf JRE und API-Klassen , wie java.lang.String und javax.servlet.http.HttpServletRequest. Sie kann jedoch nur Zugriff auf die öffentlichen Mitglieder dieser Klassen, nicht geschützt oder privat.
Eine Anwendung kann nicht reflektieren gegen alle anderen Klassen gehören nicht zu selbst, und es kann nicht die Verwendung setAccessible () Methode zur Umgehung diese Einschränkungen.
... von http://code.google.com /appengine/docs/java/runtime.html#The_Sandbox :
Ich halte würde eine benutzerdefinierte Serializer für Bitset zu schreiben.
Siehe auch: http: / /sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserializ
http://groups.google.com/group/google -gson / browse_thread / thread / 535892ffcf691aa
Andere Tipps
können Sie konstruieren GsonBuilder mit .excludeFieldsWithoutExposeAnnotation () und markieren Sie alle serialisiert Felder mit @Expose Anmerkung. In diesem Fall wird versuchen Gson nicht serialisiert Felder andere, die Sie wollen.
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.excludeFieldsWithoutExposeAnnotation();
String json = gsonBuilder.create().toJson(modelObject);
Wenn App Engine nicht Reflection unterstützt, dann sind wir ziemlich viel übrig eigene toJSON Methode zu schreiben. Dies kann wie folgt (keine große Sache, aber jemand finden könnte es nützlich):
public SampleObject {
//...
/**
* Convert this object to a JSON object for representation
*/
public JSONObject toJSON() {
try {
JSONObject jsonobj = new JSONObject();
jsonobj.put("id", this.id);
jsonobj.put("name", this.name);
return jsonobj;
} catch(Exception e) {
return null;
}
}
}
Dann können Sie eine Methode toString auf dieses Objekt verwenden, um die JSON Darstellung auszudrucken. Nicht das beste, das ich zustimmen, aber einige Abhilfe für jetzt.
Ich erlebte ein ähnliches Problem vor kurzem.
Ich war Gson läuft JSON zu analysieren und es funktionierte gut für eine lange Zeit, damit ich nicht Sorgen über GAE nicht erlaubt Reflexion auf seine Plattform.
stellte ich eine HashMap der Form-Klasse und es funktionierte gut in meinem lokalen System mit Gson perfekt JSON Parse tun.
Aber wenn ich diesen Code auf die Google App Engine Cloud bereitgestellt es mit folgenden Ausnahme fehlgeschlagen:
java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private final int java.lang.ThreadLocal.threadLocalHashCode
So jetzt habe ich zu Jackson JSON-Parser geschaltet, die schneller ist und nicht die Reflexion nicht verwendet - aber ja -. Mehr Arbeit