【问题标题】:How can I get around this invalid classloader hierarchy?如何绕过这个无效的类加载器层次结构?
【发布时间】:2009-05-06 14:43:21
【问题描述】:

我运行 iPlanet 的 Java 应用程序服务器,其中正在加载 commons-logging-1.0.4.jar

这很好,直到我的一个应用程序调用 AuthSSLProtocolSocketFactory,这是另一个也使用 commons-logging 的 apache 库。

我将 jar 放在 jvm 类路径上并收到此错误:

Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy....

似乎commons-logger 不喜欢将自己的两个实例加载到不同的类加载器中。我假设应用程序服务器有自己的类加载器,第一次加载它(虽然我找不到任何提到它的应用程序服务器配置),所以当我的应用程序第二次加载它时,它会抛出该异常。

我无法更改 Web 服务器,也无法更改 apache 库。有什么建议吗?

【问题讨论】:

    标签: java apache logging classloader


    【解决方案1】:

    看看SLF4J

    此外,http://www.qos.ch/logging/classloader.jsp 会有所帮助。

    【讨论】:

      【解决方案2】:

      您是否明确地将公共日志记录在您的类路径中?你说 jvm 类路径,所以我假设你在启动 iPlanet 时在命令行上指定它。这不是在 J2EE 应用程序中加载 jar 的推荐方式。

      最简单的方法是让 Apache 库使用 iPlanet 附带的公共日志记录 jar。不要将 commons-logging.jar 放在 WEB-INF/lib 目录或任何类路径设置中,iPlanet 应该会自动获取。

      【讨论】:

        【解决方案3】:

        不熟悉 iplanet,但在 WebSphere 中,您可以将应用程序类加载策略设置为 PARENT_LAST。然后,这将在查看父级之前加载应用程序类加载器中的所有内容。假设您有类似的设置,这应该可以解决此类问题。

        这确实意味着您必须在自己的应用程序中提供所有依赖项(无论如何这是最佳做法)。

        【讨论】:

        • 默认的 Java 类加载策略 - PARENT FIRST - 被嵌入到几乎所有已编写的 Java 类中。这些类已经在该策略下进行了测试和尝试。但是,不能保证它们可以在任何其他类加载策略下工作。切换到 PARENT LAST 类加载策略几乎总是你会后悔的事情,有时会立即后悔,经过几个月的开发。使用 PARENT LAST - 尽管它可能会解决您当前的问题 - 很可能不是您想要的。
        • @Steven Devijver 我没有遇到任何此类问题,这是让某些应用程序在 JEE 类型环境中工作的唯一方法。这也是保证您使用的是您认为的依赖类版本的唯一方法。服务器类路径上总是有类(尤其是用于 xml 解析),它们很容易干扰您自己的应用程序的独立性。您认为在这种情况下会失败的具体情况是什么?类仍然会得到解析,并且使用您与应用程序捆绑的版本,而不是在其他地方定义的版本。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-02
        • 1970-01-01
        • 2018-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多