weird behaviour of custom system classloader and M

2019-04-10 03:29发布

问题:

I have an application which uses a custom system classloader, set by the Djava.system.class.loader=class parameter. The Application uses RMI. Everything works fine out of eclipse, but if i export a runnable jar, this error happens:

Caused by: java.lang.SecurityException: SHA MessageDigest not available
    at sun.rmi.server.Util.computeMethodHash(Unknown Source)
    at sun.rmi.server.UnicastServerRef$HashToMethod_Maps.computeValue(Unknown Source)
    at sun.rmi.server.UnicastServerRef$HashToMethod_Maps.computeValue(Unknown Source)
    at sun.rmi.server.WeakClassHashMap.get(Unknown Source)
    at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)
    at sun.rmi.registry.RegistryImpl.setup(Unknown Source)
    at sun.rmi.registry.RegistryImpl.<init>(Unknown Source)
    at java.rmi.registry.LocateRegistry.createRegistry(Unknown Source)

I naturally tried to pin this problem down, and wrote a simple MessageDigest md = MessageDigest.getInstance("SHA"); as the first line in my main. Basically the same happens. The exact error is:

java.security.NoSuchAlgorithmException: SHA MessageDigest not available
    at sun.security.jca.GetInstance.getInstance(Unknown Source)
    at java.security.Security.getImpl(Unknown Source)
    at java.security.MessageDigest.getInstance(Unknown Source)

Then i tried to use a simple ClassLoader as the SystemClassloader. it now looks like this:

public class RootClassLoader extends ClassLoader{
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return super.loadClass(name);
    }

    public RootClassLoader(ClassLoader loader){
        super(loader);
    }
}

and still the same happens. If i rebuild this scenario as a new project, everything works as expected, so obviously something else is broken, but by now i have no idea what.

I dont use a security manager anywhere in the program, and i use the standard jre7 by oracle.

Anything i might have overlooked?

Update: Even if i dont override the loadClass method at all, the error occurs... It seems to fail simply because there is a non-standard system classloader, regardless of what that actually does

Update 2: I listed all the available Securityproviders/algorithms. When i execute the Code in eclipse (still with the custom classloader), everything seems in order, but while executing the runnable jar, the complete SUN version 1.7 Provider seems to be missing. Without the custom classloader, everything is the same. In a environment which contains just the szenario above (and which works) everything looks the same, and every constellation has the SUN version 1.7 Provider.

Update 3: the -verbose:class showed that the package sun.security.provider and more does not get loaded. I dont know why though, because both alternatives are loading classes from jsse.jar where the missing package comes from, and both print [Opened C:\Program Files\Java\jre7\lib\jsse.jar] (Update 4: actually it does get loaded. just much later. Even sun.security.provider.SHA gets loaded in both variants. This is even more weird)

回答1:

I found the root of this problem. I dont know why and how this actually happened, but it seems that a 3rd party lib i was using was the culprit. When i removed the lib, everything worked fine. Again, i have no idea how this is even possible