Java 自定义系统类加载器和MessageDigest的奇怪行为
我有一个应用程序,它使用一个定制的系统类加载器,由Java 自定义系统类加载器和MessageDigest的奇怪行为,java,security,classloader,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
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)
然后我尝试使用一个简单的类加载器作为系统类加载器。现在看起来是这样的:
public class RootClassLoader extends ClassLoader{
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
public RootClassLoader(ClassLoader loader){
super(loader);
}
}
公共类RootClassLoader扩展类加载器{
@凌驾
公共类loadClass(字符串名称)引发ClassNotFoundException{
返回super.loadClass(名称);
}
公共根类加载器(类加载器){
超级装载机;
}
}
同样的情况也会发生。如果我把这个场景重建为一个新项目,一切都会按预期进行,所以很明显,其他的东西都坏了,但现在我不知道是什么
我在程序中的任何地方都不使用安全管理器,我使用oracle的标准jre7
有什么我可能忽略的吗
更新:
即使我根本不重写loadClass
方法,也会发生错误。。。它似乎失败仅仅是因为有一个非标准的系统类加载器,而不管它实际做什么
更新2:
我列出了所有可用的Securityproviders/算法。当我在eclipse中执行代码时(仍然使用自定义类加载器),一切似乎都正常,但是在执行runnable jar时,完整的SUN 1.7版
提供程序似乎丢失了。没有自定义类加载器,一切都是一样的。在一个只包含上述szenario(并且可以工作)的环境中,一切看起来都是一样的,每个星座都有SUN 1.7版
提供程序
更新3:
-verbose:class
显示包sun.security.provider
及更多未加载。我不知道为什么,因为这两种方法都是从jsse.jar
中加载类,缺少的包来自哪里,并且都打印[Opened C:\Program Files\Java\jre7\lib\jsse.jar]
(更新4:事实上,它确实被加载了。只是在很久以后。甚至sun.security.provider.SHA
在两个变体中都被加载了。这更奇怪)我找到了这个问题的根源。我不知道为什么会发生这种情况,也不知道是怎么发生的,但我使用的第三方库似乎是罪魁祸首。当我删除该库时,一切正常。同样,我不知道这是怎么可能的。这里有一些有趣的答案,你甚至可以检查你的运行时支持什么算法。,谢谢,我更新了我的问题OK,我没有任何线索,但是在自定义类加载器上运行时,是否需要在类路径中手动提供包含摘要和加密类的JAR?也许eclipse已经在这样做了。如果在这两种情况下都使用verbose:class
选项运行java
启用并查看加载了哪些类?谢谢,我再次更新了。但我不认为这是问题的根源,因为如果我尝试重新创建问题,它会起作用。您建议的代码对我有效!。在eclipse外部。我打印MessageDigest
以从SUN获取SHA消息摘要,
。我确信您会使用checked,但以防万一,您是否使用与eclipse相同的jre?
public class RootClassLoader extends ClassLoader{
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
public RootClassLoader(ClassLoader loader){
super(loader);
}
}