2010-06-09 24 views
8

Tôi đang cố gắng chuyển đổi một đối tượng thành JSON bằng cách sử dụng thư viện GSON trên Google App Engine. Vì lý do nào đó, nó ném ngoại lệ này và tôi không hiểu làm thế nào để giải quyết vấn đề này. Bất kỳ đề xuất?GSON trên Google App Engine ném một ngoại lệ bảo mật

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) 

Mã Tôi đang sử dụng:

Gson gson = new Gson(); 
String json = gson.toJson(modelObject); 
+1

Tính năng phản chiếu này có thể không có sẵn trên App Engine. Đó là lạ, mặc dù, rằng AccessibleObject được liệt kê trong danh sách trắng JRE: http://code.google.com/appengine/docs/java/jrewhitelist.html –

+0

@ Jason: Cảm ơn bạn đã trả lời. Điều đó có nghĩa là tôi cần phải viết các phương thức toJSON của riêng mình: ( – Legend

+2

Phản ánh có sẵn trên App Engine - nhưng dường như đối tượng cụ thể đó không có giới hạn. một bitSet trên JSON? –

Trả lời

3

Các công cụ ứng dụng không phản ánh sự ủng hộ - tuy nhiên bạn đang cố gắng suy nghĩ về một lĩnh vực riêng của lớp JRE:

Reflection

Đơn được phép đầy đủ, không hạn chế, phản ánh quyền truy cập vào nó các lớp học riêng. Nó có thể truy vấn bất kỳ thành viên riêng nào, sử dụng java.lang.reflect.AccessibleObject.setAccessible(), và đọc/đặt thành viên riêng tư.

Đơn cũng có thể cũng phản ánh trên JRE và API lớp như java.lang.String và javax.servlet.http.HttpServletRequest. Tuy nhiên, chỉ có thể truy cập công khai thành viên của các lớp này, chứ không phải được bảo vệ hoặc riêng tư.

Một ứng dụng không thể phản ánh chống lại bất kỳ lớp khác không thuộc chính nó, và nó không thể sử dụng phương pháp setAccessible() để phá vỡ những hạn chế này.

... từ http://code.google.com/appengine/docs/java/runtime.html#The_Sandbox:

Tôi muốn xem xét viết một serializer tùy chỉnh cho BitSet.

Xem: http://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserializ

Ngoài ra: http://groups.google.com/group/google-gson/browse_thread/thread/535892ffcf691aa/897f27e37e03ce58?lnk=gst&q=bitset#897f27e37e03ce58

http://groups.google.com/group/google-gson/browse_thread/thread/535892ffcf691aa

+0

Cảm ơn bạn.Tôi đoán trong trường hợp của tôi, tôi không chắc chắn tại sao GSON đang làm những gì nó đang làm :) Nếu bạn biết bất kỳ cách nào khác để làm cho nó hoạt động , nó sẽ rất tuyệt. – Legend

+0

Không có wukka. Có lẽ regisiter một serializer tùy chỉnh cho Bitset? –

+0

Cảm ơn bạn đã đề xuất. Tôi sẽ nhìn vào nó. – Legend

0

Nếu App Engine không hỗ trợ Reflection, sau đó chúng tôi được khá nhiều trái để viết phương pháp toJSON của chúng ta. Điều này có thể được thực hiện như sau (không phải là vấn đề lớn nhưng ai đó có thể thấy nó hữu ích):

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; 
    } 
    } 
} 

Sau đó, bạn có thể sử dụng phương thức toString trên đối tượng này để in ra biểu diễn JSON. Không phải là tốt nhất tôi đồng ý nhưng một số workaround cho bây giờ.

1

Bạn có thể xây dựng GsonBuilder với .excludeFieldsWithoutExposeAnnotation(), và đánh dấu tất cả các lĩnh vực serialized với chú thích @Expose. Trong trường hợp này, Gson không cố gắng tuần tự hóa các trường khác mà bạn muốn.

GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.excludeFieldsWithoutExposeAnnotation(); 
String json = gsonBuilder.create().toJson(modelObject); 
0

Tôi gặp phải sự cố tương tự gần đây.

Tôi đã chạy Gson để phân tích JSON và nó hoạt động tốt trong một thời gian dài vì vậy tôi không lo lắng về GAE không cho phép Reflection trên nền tảng của nó.

Tôi đã giới thiệu một lớp HashMap the Form và nó hoạt động tốt trong hệ thống cục bộ của tôi với Gson làm JSON Parse hoàn hảo.

Nhưng khi tôi triển khai mã của Google App Engine của Cloud nó thất bại với các ngoại lệ sau đây:

java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private final int java.lang.ThreadLocal.threadLocalHashCode 

Vì vậy, bây giờ tôi đã chuyển sang Jackson JSON Parser đó là nhanh hơn và không sử dụng phản ánh - nhưng vâng - nhiều việc hơn.

Các vấn đề liên quan