GSON sur Google App Engine lance une exception de sécurité
-
25-09-2019 - |
Question
Je suis en train de convertir un objet en JSON en utilisant la bibliothèque GSON sur Google App Engine. Pour une raison quelconque, il jette cette exception et je ne comprends pas comment résoudre ce problème. Toutes les suggestions?
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)
J'utilise le code:
Gson gson = new Gson();
String json = gson.toJson(modelObject);
La solution
Le moteur app ne soutenir la réflexion - mais vous essayez de réfléchir sur un champ privé d'une classe JRE:
Réflexion
Une application est autorisée pleine, un accès illimité, réfléchissant à sa propres classes. Il peut interroger un privé membres, l'utilisation java.lang.reflect.AccessibleObject.setAccessible (), et lecture / set membres privés.
Une application peut également refléter aussi sur les classes de l'API et JRE , comme java.lang.String et javax.servlet.http.HttpServletRequest. Toutefois, il ne peut l'accès du public les membres de ces classes, et non protégé ou privé.
Une application ne peut pas refléter contre toutes les autres classes ne faisant pas partie lui-même, et il ne peut pas utiliser la Procédé setAccessible () pour contourner ces restrictions.
... à partir de http://code.google.com /appengine/docs/java/runtime.html#The_Sandbox :
Je considère l'écriture d'un sérialiseur personnalisé pour Bitset.
Voir: http: / /sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserializ
http://groups.google.com/group/google -gson / browse_thread / fil / 535892ffcf691aa
Autres conseils
Vous pouvez construire GsonBuilder avec .excludeFieldsWithoutExposeAnnotation (), et marquer tous les champs avec un numéro de série annotation @Expose. Dans ce cas, Gson ne cherche pas à sérialiser champs autres que vous voulez.
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.excludeFieldsWithoutExposeAnnotation();
String json = gsonBuilder.create().toJson(modelObject);
Si App Engine ne prend pas en charge la réflexion, nous sommes à peu près à gauche pour écrire notre propre méthode de toJSON. Cela peut se faire comme suit (pas une grosse affaire, mais quelqu'un pourrait trouver utile):
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;
}
}
}
Ensuite, vous pouvez utiliser une méthode toString sur cet objet pour imprimer la représentation JSON. Pas le meilleur Je suis d'accord, mais une solution de contournement pour l'instant.
J'ai connu un problème similaire récemment.
Je courais Gson pour analyser JSON et cela a bien fonctionné pendant longtemps, donc je ne me préoccupais GAE ne permettant pas la réflexion sur sa plate-forme.
J'introduit un HashMap la classe Form et cela a bien fonctionné dans mon système local avec Gson faire JSON Parse parfaitement.
Mais quand je déployé ce code à Google App Cloud Engine il a échoué à l'exception suivante:
java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private final int java.lang.ThreadLocal.threadLocalHashCode
Alors maintenant, je suis passé à Jackson JSON Parser qui est plus rapide et ne pas utiliser la réflexion - mais oui -. Plus de travail