我有一个使用自定义系统类加载器的应用程序,由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
都加载了两种变体。这更奇怪了)
答案 0 :(得分:0)
我找到了这个问题的根源。我不知道为什么以及如何实际发生,但似乎我使用的第三方lib是罪魁祸首。当我删除lib时,一切正常。再一次,我不知道这是怎么可能的