【问题标题】:weird behaviour of custom system classloader and MessageDigest自定义系统类加载器和 MessageDigest 的奇怪行为
【发布时间】:2013-08-20 12:13:17
【问题描述】:

我有一个使用自定义系统类加载器的应用程序,由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: 我列出了所有可用的安全提供者/算法。当我在 Eclipse 中执行代码时(仍然使用自定义类加载器),一切似乎都井井有条,但是在执行可运行 jar 时,似乎缺少完整的 SUN version 1.7 Provider。没有自定义类加载器,一切都是一样的。在仅包含上述场景(并且有效)的环境中,一切看起来都一样,并且每个星座都有SUN version 1.7 Provider。

更新 3: -verbose:class 显示包 sun.security.provider 和更多包没有被加载。我不知道为什么,因为这两种选择都是从缺少包的来源jsse.jar 加载类,并且都打印[Opened C:\Program Files\Java\jre7\lib\jsse.jar] (更新4:实际上它确实被加载了。只是很久以后。甚至sun.security.provider.SHA 都加载了两种变体。这更奇怪)

【问题讨论】:

  • 这里有一些有趣的答案,您甚至可以检查您的运行时支持哪些算法。 stackoverflow.com/questions/14903539/…,
  • 谢谢,我更新了我的问题
  • 好吧,我不知道,但在自定义类加载器上运行时,是否需要在类路径中手动提供包含摘要和加密类的 jar?也许 Eclipse 已经在这样做了。如果您在启用verbose:class 选项的两种情况下运行java 并查看加载了哪些类?
  • 谢谢,我又更新了。我不认为这是问题的根源,因为如果我尝试重新创建问题,它会起作用
  • 你建议的代码对我有用!。外食。我打印MessageDigest 得到SHA Message Digest from SUN, &lt;initialized&gt;。我相信您会检查过,但以防万一,您使用的 jre 与 eclipse 中的相同吗?

标签: java security classloader


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    • 2014-10-18
    • 1970-01-01
    • 2011-07-06
    • 2014-08-25
    • 1970-01-01
    • 2014-10-06
    相关资源
    最近更新 更多