【问题标题】:NoClassDefFoundError loading class with URLClassLoaderNoClassDefFoundError 使用 URLClassLoader 加载类
【发布时间】:2018-06-29 19:14:50
【问题描述】:

我们正在尝试为我们的产品支持插件,我正在使用反射从 jar 中加载类。

我创建了一个 URL 类加载器并将所有依赖 jar 添加为 URL。

我使用那个 ClassLaoder 来加载插件的主类。

我得到了一个类的实例和一个方法引用(一个 run() 方法)。

当我调用该方法时,我得到了这个异常:

java.lang.NoClassDefFoundError: 无法初始化类 org.apache.logging.log4j.util.PropertiesUtil

这个类在log4j-api-2.10.0.jar中,包含在ClassLoader的类路径中。

我可以在调试中看到类加载器中的 URL,因此我知道它被正确引用了。

有时我得到一个不同的错误,说它无法初始化我的一个类,但那个类没有什么特别的,没有静态或任何东西。

通过反射加载的主要类正在调用使用 Log4j 2 的第二个类。

当主类 run() 方法尝试实例化第二个类时,就会出现此问题。

除了 Logger 之外,这两个类都没有静态的。

在调试器中,我可以从 Method ref 中看到该类确实是使用我们创建的 URL ClassLoader 加载的。

这段代码已经运行了十年,我们唯一改变的是插件中升级到 Log4j 2。 进行反射插件加载的类只是应用程序类路径中的一个普通类。

任何帮助将不胜感激。

根据 Drizzle 的建议,我得到:

Exception in thread "ServerStatus:update_timer:" java.lang.ExceptionInInitializerErrorException in thread "ServerStatus:update_timer:" java.lang.ExceptionInInitializerError
    at java.lang.Class.forName0(Native Method)  at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)  at java.lang.Class.forName(Unknown Source)
    at ...
    at java.lang.Thread.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: java.util.Vector cannot be cast to java.lang.StringCaused by: java.lang.ClassCastException: java.util.Vector cannot be cast to java.lang.String
    at org.apache.logging.log4j.util.SystemPropertiesPropertySource.forEach(SystemPropertiesPropertySource.java:39)
    at org.apache.logging.log4j.util.SystemPropertiesPropertySource.forEach(SystemPropertiesPropertySource.java:39)
    at org.apache.logging.log4j.util.PropertiesUtil$Environment.reload(PropertiesUtil.java:330) at org.apache.logging.log4j.util.PropertiesUtil$Environment.reload(PropertiesUtil.java:330)
    at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:322) at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:322)
    at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:310) at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:310)
    at org.apache.logging.log4j.util.PropertiesUtil.<init>(PropertiesUtil.java:69)  at org.apache.logging.log4j.util.PropertiesUtil.<init>(PropertiesUtil.java:69)
    at org.apache.logging.log4j.util.PropertiesUtil.<clinit>(PropertiesUtil.java:49)    at org.apache.logging.log4j.util.PropertiesUtil.<clinit>(PropertiesUtil.java:49)

更新:Log4j 2 版本 2.10.x 及更高版本存在错误。加载类反射性地揭示了错误。切换回 2.8.2,上述异常消失。但是,现在我仍然为我的一门课程获得 ClassNotFound。

【问题讨论】:

  • 如何创建URLClassLoader
  • new URLClassLoader(getPluginClassPath(url), Thread.currentThread().getContextClassLoader()); getPluginClassPath() 只是为依赖项创建所有 URL
  • 正如您在上面看到的,Log4j 2 存在问题。就构建环境而言,这将无济于事。它非常复杂,使用了许多技术。这不是构建问题。

标签: java reflection urlclassloader


【解决方案1】:

支持 Log4j 到 2.8.2 已解决问题。它是 Log4j 上的一个错误。谢谢您的帮助。很难找到的人。

【讨论】:

    【解决方案2】:

    这可能有助于解决java.lang.NoClassDefFoundError

    try {
        Class.forName("org.apache.logging.log4j.util.PropertiesUtil");
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    【讨论】:

    • 好主意会尝试
    • 我不相信这会有所帮助 - OP 在执行代码时可能会遇到 NoClassDefFoundError。 OP 的问题是他们的类路径不包含依赖项,并且 @K.Taylor - 请使用您的构建环境(Maven、Gradle、普通 Eclipse 等)更新问题,整个社区将是更好地回答您的问题。
    • 那么为什么这个答案被否决,提供了解决方案,考虑到所需的库包含在应用程序中。
    • 不知道。我投了赞成票。如果它接受它,我会再做一次。实际上,这就是 Log4j 中显示的错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 2011-06-07
    • 2014-09-01
    • 1970-01-01
    相关资源
    最近更新 更多