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:
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!
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!