自定义系统类加载器和MessageDigest的奇怪行为

时间:2013-08-20 12:13:18

标签: java security classloader

我有一个使用自定义系统类加载器的应用程序,由Djava.system.class.loader=class参数设置。该应用程序使用RMI。在Eclipse中一切正常,但如果我导出一个可运行的jar,则会发生以下错误:

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)

我自然试图解决这个问题,并写了一个简单的MessageDigest md = MessageDigest.getInstance("SHA");作为我主要的第一行。基本上也是如此。确切的错误是:

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)

然后我尝试使用一个简单的ClassLoader作为SystemClassloader。它现在看起来像这样:

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

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

仍然是一样的。如果我将这个场景重建为一个新项目,一切都按预期工作,所以很明显其他东西都被破坏了,但到现在为止我还不知道是什么。

我不在程序的任何地方使用安全管理器,我使用oracle的标准jre7。

我可能忽略了什么?

更新 即使我根本不重写loadClass方法,也会发生错误...它似乎失败只是因为有一个非标准的系统类加载器,无论实际做什么

更新2: 我列出了所有可用的Securityproviders /算法。当我在eclipse中执行代码时(仍然使用自定义类加载器),一切看起来都是有序的,但是在执行runnable jar时,似乎缺少完整的SUN version 1.7提供程序。没有自定义类加载器,一切都是一样的。在一个只包含上面的szenario(并且可以工作)的环境中,一切看起来都是一样的,每个星座都有SUN version 1.7提供者。

更新3: -verbose:class显示包sun.security.provider和更多内容未加载。我不知道为什么,因为两个替代方案都是从jsse.jar加载丢失包来自的类,并且都打印[Opened C:\Program Files\Java\jre7\lib\jsse.jar](更新4:实际上它 加载。很久以后。甚至sun.security.provider.SHA都加载了两种变体。这更奇怪了)

1 个答案:

答案 0 :(得分:0)

我找到了这个问题的根源。我不知道为什么以及如何实际发生,但似乎我使用的第三方lib是罪魁祸首。当我删除lib时,一切正常。再一次,我不知道这是怎么可能的