Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 自定义系统类加载器和MessageDigest的奇怪行为_Java_Security_Classloader - Fatal编程技术网

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);
    }
}