3

I'm trying to use Google Gson in my Java Applet, but when I do I get

Exception in thread "Thread-19" java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:74) at com.google.gson.MappedObjectConstructor.getNoArgsConstructor(MappedObjectConstructor.java:85) at com.google.gson.MappedObjectConstructor.constructWithNoArgConstructor(MappedObjectConstructor.java:62) at com.google.gson.MappedObjectConstructor.construct(MappedObjectConstructor.java:53) at com.google.gson.JsonObjectDeserializationVisitor.constructTarget(JsonObjectDeserializationVisitor.java:40) at com.google.gson.JsonDeserializationVisitor.getTarget(JsonDeserializationVisitor.java:56) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:109) at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:73) at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:51) at com.google.gson.Gson.fromJson(Gson.java:495) at com.google.gson.Gson.fromJson(Gson.java:444) at com.google.gson.Gson.fromJson(Gson.java:396) at com.google.gson.Gson.fromJson(Gson.java:372) at org.jblux.client.network.GsonParser$1.run(GsonParser.java:32) at java.security.AccessController.doPrivileged(Native Method) at org.jblux.client.network.GsonParser.parseJson(GsonParser.java:36) at org.jblux.client.network.PlayerDataFactory.getDataFromBase64(PlayerDataFactory.java:36) at org.jblux.client.states.MainMenuState.update(MainMenuState.java:155) at java.util.Observable.notifyObservers(Observable.java:142) at org.jblux.client.network.ResponseWaiter.responseReceived(ResponseWaiter.java:33) at org.jblux.client.network.ServerListener.notify_observers(ServerCommunicator.java:236) at org.jblux.client.network.ServerListener.doCommand(ServerCommunicator.java:252) at org.jblux.client.network.ServerListener.run(ServerCommunicator.java:218)

There were two other related questions I found here.
GSON on Google App Engine throws a Security Exception
Reflection Permission problems when using the GSON library in a applet

But neither of them had an answer for me. One just said to not use Gson.
Is there any way to grant Reflection permission to my applet?

Update: I'm in the process of switching my application to use JNLP file and Java Web Start because I haven't been able to figure out how to make the Applet work. I'll leave this question open in case anybody figures it out, but using a JNLP may be the only option if you don't want to give up Gson.

Community
  • 1
  • 1
jonescb
  • 22,013
  • 7
  • 46
  • 42
  • 1
    One of the answers in the second related question suggested to sign the applet or to execute a `PrivilegedAction`. Did you try one or other? – BalusC Oct 03 '10 at 17:50
  • Yeah, my applet has always been signed, and I tried the PrivelagedAction thing but that didn't work. PrivelagedAction even shows up in the backtrace I posted. – jonescb Oct 03 '10 at 18:29
  • There's a call to setAccessible late in the stack trace. What's the visibility on your no argument constructor? If not already, try setting it to public to see if that gets you past this. If already public, might need to file a bug w/ the GSON folks to not change the accessibility when already visible. – Carl Oct 03 '10 at 20:25

3 Answers3

2

I solved this problem using a custom deserializer.

I had a class with two members, a timestamp and a list of doubles. This is the code that worked for me.

GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(TimestampedValueList.class, new JsonDeserializer<TimestampedValueList>() {
        @Override
        public TimestampedValueList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            long timestampMs = json.getAsJsonObject().get("timestampMs").getAsLong();
            double[] valueList = context.deserialize(json.getAsJsonObject().get("valueList"), double[].class);
            return new TimestampedValueList(timestampMs, valueList);
        }
    });
gson = gsonBuilder.create();

Hope this can help anyone!

Coding Mash
  • 3,338
  • 5
  • 24
  • 45
Chrizzz
  • 21
  • 2
0

I have found the answer here.

System.setSecurityManager(null);

Adding to static main helped me. Of course, all-permissions in jnlp and so on must be.

Stephan
  • 41,764
  • 65
  • 238
  • 329
0

Further to @Chrizzz, I'm doing two way command object exchange between a Java web server and an unsigned applet. As such I am using both Gson toJson() and fromJson() within my applet code.

I've found that both deserialization and serialization in an unsigned applet throw security exceptions and that implementing custom serializers and deserializers can work-around those problems.

The biggest pain is not being able emulate the applet environment (SecurityManager) for Unit testing. It seems that there are no frameworks available to do this: see e.g. How to unit test Java code that is expected to run within an applet Security Manager

Community
  • 1
  • 1
user598656
  • 442
  • 7
  • 10