Question

I have a little Java Applet and I have an annoying issue. I have signed my JAR with my own keystore using jarsigner tool (following these instructions).

The Java Applet downloads a signed JAR and tries to launch it with an extended class of URLClassLoader. This JAR tries to execute this line of code:

ClassLoader.getSystemClassLoader().getResource("aResource");

It fails with a large stack trace finished by:

Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
    at java.security.AccessController.checkPermission(AccessController.java:555)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1476)
    at test.SecondJAR.main(SecondJAR.java:8)

(Line 8 of test.SecondJAR corresponds to getResource(...) method

When the Java Applet is launched, the user is prompted to accept the certificate if he/she trusts the publisher:

Message to the user

Even if I accept it, the exception occurred. Even if I install the certificate, and the prompt message is automatically accepted, the exception occurred.

I have tried too this:

AccessController.doPrivileged(new PrivilegedAction<Object>() {
    public Object run() {
        ClassLoader.getSystemClassLoader().getResource("aResource");
        return null;
    }
});

And it fails with the same exception.

Any help would be appreciated!

Was it helpful?

Solution

Finally I have found the answer!

I followed the guidelines of Andrew Thomson and I created a custom SecurityManager. My little security manager looks like this:

private class MySecurityManager extends SecurityManager {
    @Override
    public void checkPermission(Permission perm) {
        return;
    }
}

It is a neglected security manager that accepts all permissions. It should be improved allowing only getting system ClassLoader in runtime.

To use my ugly SecurityManager I added these lines at the beginning of Java Applet start() method:

SecurityManager sm = new MySecurityManager();
System.setSecurityManager(sm);

With this workaround, all the process worked as expected!

Maybe there exist other (better) solutions, but it worked for me.

Thank you all!

OTHER TIPS

The problem is that the JRE only considers code in the original code-base to be trusted. Two possible solutions are:

  1. Set a custom security manager that allows the new code to have the privileges it requires.
  2. Wrap the new code in a PrivilegedAction & call it from AccessController.doPrivileged(..) method (just occurred to me as a possibility, not sure if I understand the scope of it, completely untested).
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top