【问题标题】:Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger引起:java.lang.NoClassDefFoundError: org/apache/log4j/Logger
【发布时间】:2014-01-03 17:34:40
【问题描述】:

我遇到了一个有趣的问题,即在运行时找不到 org.apache.log4j.Logger 类。我正在尝试获得授权,但这就是失败的地方:

OAuthAuthorizer oauthAuthorizer = new OAuthAuthorizer(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, SAML_PROVIDER_ID, userId);

我使用的是 JDeveloper 11.1.1.6。以下是我所知道的:

  1. 我查看了我的 UI.war/WEB-INF/lib 目录,并在其中看到了 log4j-1.2.17.jar。

  2. 抱怨它的类是 org.opensaml.xml.XMLConfigurator

    Caused by: java.lang.NoClassDefFoundError: org/apache/log4j/Logger
        at org.opensaml.xml.XMLConfigurator.<clinit>(XMLConfigurator.java:60)
        at org.opensaml.DefaultBootstrap.initializeXMLTooling(DefaultBootstrap.java:195)
        at org.opensaml.DefaultBootstrap.bootstrap(DefaultBootstrap.java:91)
        at com.intuit.ipp.aggcat.util.SAML2AssertionGenerator.getSAMLBuilder(SAML2AssertionGenerator.java:156)
        at com.intuit.ipp.aggcat.util.SAML2AssertionGenerator.createSubject(SAML2AssertionGenerator.java:187)
        at com.intuit.ipp.aggcat.util.SAML2AssertionGenerator.buildAssertion(SAML2AssertionGenerator.java:114)
        at com.intuit.ipp.aggcat.util.SAML2AssertionGenerator.generateSignedAssertion(SAML2AssertionGenerator.java:83)
        at com.intuit.ipp.aggcat.util.SamlUtil.createSignedSAMLPayload(SamlUtil.java:156)
        at com.intuit.ipp.aggcat.util.OAuthUtil.getOAuthTokens(OAuthUtil.java:60)
        at com.intuit.ipp.aggcat.core.OAuthAuthorizer.<init>(OAuthAuthorizer.java:85)
        at com.incomemax.view.intuit.WebUtil.getAggCatService(WebUtil.java:91)
    
    Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:305)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:246)
        ... 64 more
    
  3. 我反编译了 XMLConfigurator,奇怪的是它没有导入 org.apache.log4j.Logger 它使用 org.slf4j.Logger,它也在我的 jars 目录 (slf4j-api-1.7.5.jar) 中。同样有趣的是,第 60 行(参见堆栈跟踪)在我的反编译中是一个空白行。

  4. 当然,如果我在设计时添加 Logger.xxxxx,它会觉得很好。

  5. 我直接使用示例 java 代码中的代码/jar,但导入到我现有的应用程序中。

我一直在网上搜索答案,我相信我已经检查了所有我能想到的领域。我还引用了这个非常好的页面:http://myarch.com/classnotfound/

鉴于授权是使用 Intuit Developer API 的第一步,我有点卡住了。

添加来自@jhadesdev 建议的输出:

log4j Logger的所有版本:

  • zip:C:/Users/Chris/AppData/Roaming/JDeveloper/system11.1.1.6.38.61.92/DefaultDomain/servers/DefaultServer/tmp/_WL_user/j2ee-app/lt5l71/war/WEB-INF/lib/ log4j-1.2.17.jar!/org/apache/log4j/Logger.class

从 OAuthAuthorizer 类的类加载器可见的所有 log4j 版本:

  • zip:C:/Users/Chris/AppData/Roaming/JDeveloper/system11.1.1.6.38.61.92/DefaultDomain/servers/DefaultServer/tmp/_WL_user/j2ee-app/lt5l71/war/WEB-INF/lib/ log4j-1.2.17.jar!/org/apache/log4j/Logger.class

所有版本的 XMLConfigurator:

  • jar:file:/C:/Oracle/Middleware11116/modules/com.bea.core.bea.opensaml2_1.0.0.0_6-1-0-0.jar!/org/opensaml/xml/XMLConfigurator .class

  • zip:C:/Users/Chris/AppData/Roaming/JDeveloper/system11.1.1.6.38.61.92/DefaultDomain/servers/DefaultServer/tmp/_WL_user/j2ee-app/lt5l71/war/WEB-INF /lib/ipp-java-aggcat-v1-devkit-1.0.2.jar!/org/opensaml/xml/XMLConfigurator.class

  • zip:C:/Users/Chris/AppData/Roaming/JDeveloper/system11.1.1.6.38.61.92/DefaultDomain/servers/DefaultServer/tmp/_WL_user/j2ee-app/lt5l71/war/WEB-INF /lib/xmltooling-1.3.1.jar!/org/opensaml/xml/XMLConfigurator.class

从 OAuthAuthorizer 类的类加载器可见的所有 XMLConfigurator 版本:

  • jar:file:/C:/Oracle/Middleware11116/modules/com.bea.core.bea.opensaml2_1.0.0.0_6-1-0-0.jar!/org/opensaml/xml/XMLConfigurator .class

  • zip:C:/Users/Chris/AppData/Roaming/JDeveloper/system11.1.1.6.38.61.92/DefaultDomain/servers/DefaultServer/tmp/_WL_user/j2ee-app/lt5l71/war/WEB-INF /lib/ipp-java-aggcat-v1-devkit-1.0.2.jar!/org/opensaml/xml/XMLConfigurator.class

  • zip:C:/Users/Chris/AppData/Roaming/JDeveloper/system11.1.1.6.38.61.92/DefaultDomain/servers/DefaultServer/tmp/_WL_user/j2ee-app/lt5l71/war/WEB-INF /lib/xmltooling-1.3.1.jar!/org/opensaml/xml/XMLConfigurator.class

我仍在努力解释结果。

【问题讨论】:

  • 如果您使用的是 Tomcat 8 并已符号链接您的 Web 应用程序中的任何文件夹,您需要有一个 allowLinking 属性:&lt;Context&gt;&lt;Resources allowLinking="true"/&gt; in $CATALINA_HOME/conf/context.xml

标签: java logging classpath classloader intuit-partner-platform


【解决方案1】:

在运行时,您的应用程序无法找到 jar。

取自this answerJared

重要的是要让我们头脑清楚地记住两个不同的例外情况 在这种情况下:

  1. java.lang.ClassNotFoundException 这是一个Exception,它表示 在类路径中找不到类。这表明我们在 试图加载类定义,并且该类不存在 类路径。

  2. java.lang.NoClassDefFoundError 这是Error,表示JVM 查看其内部类定义数据结构 定义了一个类,并没有找到它。这不同于 说它无法从类路径加载。通常这个 表示我们之前尝试从 类路径,但由于某种原因它失败了 - 现在我们再次尝试, 但我们甚至不会尝试加载它,因为我们失败了 提前加载它。早期的失败可能是 ClassNotFoundException 或 ExceptionInInitializerError(表示 静态初始化块中的失败)或任何数量的其他 问题。关键是,NoClassDefFoundError 不一定是 类路径问题。

for similarities and differences

【讨论】:

  • 很好的解释@premraj。基于此,我在代码开头添加了LOG.error("Just entered getAggCatService");,并确保我的导入是 org.apache.log4j.Logger。显示了我的日志消息。这不是意味着 org.apache.log4j.Logger 被加载然后找到了吗?
【解决方案2】:

您可以在 pom 文件中使用以下 maven 依赖项。否则,您可以从 net 下载以下两个 jar 并将其添加到您的构建路径中。

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.6.4</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.4</version>
</dependency>

这是从我的工作项目中复制的。首先确保它在您的项目中工作。然后您可以更改版本以使用任何其他(版本)兼容的 jar。

对于 AggCat,您可以参考示例 java 应用程序的 POM 文件。

https://github.com/IntuitDeveloperRelations/IPP_Sample_Code/blob/master/CustomerAccountData/Java/AggCatSampleApplication/pom.xml

谢谢

【讨论】:

  • 我的构建在 Eclipse 中工作,但在 MAC 上的命令行失败。问题是我错过了这个解决方案中的第二个工件。 slf4j-log4j12。我猜eclipse默认包含它。
  • 添加 lof4j-over-slf4j 解决了这个问题。 slf4j-log4j12 为 log4j 依赖项添加错误 org.slf4jlog4j-over-slf4j${slf4j-api.version}依赖>
  • 我从spring-kafka-test 及其zookeeper 依赖项中收到此错误。添加slf4j-log4j12 作为测试范围的依赖项为我解决了这个问题。
  • 就像一个魅力。我正在使用 Big Queue github.com/bulldog2011/bigqueue 并且发生了这个错误。希望这对任何人都有帮助
【解决方案3】:

签入部署程序集,

我有同样的错误,当我使用“maven clean install”方式生成war文件并手动部署时,它工作正常,但是当我使用运行时环境(eclipse)时,问题就来了。

我的解决方案(对于 Eclipse IDE)转到:“proyect properties”-->“Deployment Assembly”->“Add”-->“the jar you need”,在我的例子中是 java“构建路径条目”。 或许能帮上一点忙!

【讨论】:

    【解决方案4】:

    根据@jhadesdev 的建议和其他人的解释,我在这里找到了问题。

    添加代码以查看各种类加载器可见的内容后,我发现:

    All versions of log4j Logger: 
      zip:<snip>war/WEB-INF/lib/log4j-1.2.17.jar!/org/apache/log4j/Logger.class
    
    All versions of log4j visible from the classloader of the OAuthAuthorizer class: 
      zip:<snip>war/WEB-INF/lib/log4j-1.2.17.jar!/org/apache/log4j/Logger.class
    
    All versions of XMLConfigurator: 
      jar:<snip>com.bea.core.bea.opensaml2_1.0.0.0_6-1-0-0.jar!/org/opensaml/xml/XMLConfigurator.class
      zip:<snip>war/WEB-INF/lib/ipp-java-aggcat-v1-devkit-1.0.2.jar!/org/opensaml/xml/XMLConfigurator.class
      zip:<snip>war/WEB-INF/lib/xmltooling-1.3.1.jar!/org/opensaml/xml/XMLConfigurator.class
    
    All versions of XMLConfigurator visible from the classloader of the OAuthAuthorizer class: 
      jar:<snip>com.bea.core.bea.opensaml2_1.0.0.0_6-1-0-0.jar!/org/opensaml/xml/XMLConfigurator.class
      zip:<snip>war/WEB-INF/lib/ipp-java-aggcat-v1-devkit-1.0.2.jar!/org/opensaml/xml/XMLConfigurator.class
      zip:<snip>war/WEB-INF/lib/xmltooling-1.3.1.jar!/org/opensaml/xml/XMLConfigurator.class
    

    我注意到另一个版本的 XMLConfigurator 可能会被选中。 我反编译了那个类,并在第 60 行找到了这个(错误在原始堆栈跟踪中)private static final Logger log = Logger.getLogger(XMLConfigurator.class);,并且该类是从 org.apache.log4j.Logger 导入的!

    所以加载和使用的正是这个类。我的解决方法是重命名包含此文件的 jar 文件,因为我找不到显式或间接加载它的位置。这在我实际部署时可能会造成问题。

    感谢所有帮助以及关于加载类的急需课程。

    【讨论】:

      【解决方案5】:

      根据堆栈跟踪,一个 intuit 类 com.intuit.ipp.aggcat.util.SAML2AssertionGenerator 在类路径上需要一个 saml jar。

      一个 saml 类 org.opensaml.xml.XMLConfigurator 需要轮到 log4j,它在 WAR 里面但是找不到它。

      对此的一种解释是,需要 log4j 的 XMLConfigurator 类不是在 WAR 中而是在下游类加载器上找到的。 WAR 中是否缺少 saml jar?

      需要 log4j 的类 XMLConfigurator 在加载它的类加载器级别找不到它,并且 WAR 上的 log4j 版本在该特定类加载器上不可见。

      为了解决这个问题,一种方法是在 oauth 调用之前添加:

      System.out.println("all versions of log4j Logger: " + getClass().getClassLoader().getResources("org/apache/log4j/Logger.class") );
      
      System.out.println("all versions of XMLConfigurator: " + getClass().getClassLoader().getResources("org/opensaml/xml/XMLConfigurator.class") );
      
      System.out.println("all versions of XMLConfigurator visible from the classloader of the OAuthAuthorizer class: " + OAuthAuthorizer.class.getClassLoader().getResources("org/opensaml/xml/XMLConfigurator.class") );
      
      System.out.println("all versions of log4j visible from the classloader of the OAuthAuthorizer class: " + OAuthAuthorizer.class.getClassloader().getResources("org/apache/log4j/Logger.class") );
      

      另外,如果您使用的是 Java 7,请查看 jHades,这是我为帮助解决此类问题而制作的工具。

      为了看看发生了什么,您能否发布上面的类路径查询的结果,这是针对哪个容器,tomcat,码头?以防万一,最好将完整的堆栈跟踪以及所有引起的原因放在 pastebin 中。

      【讨论】:

      • 我添加了您建议的代码。我只需要弄清楚如何粘贴它,因为它对于stackoverflow中的评论字段来说太长了。
      • 忘记添加...我在 Weblogic server 11g 中运行,所以这将是 Derby 服务器
      【解决方案6】:

      遇到同样的问题,确实是weblogic愚蠢地使用了自己的opensaml实现造成的。为了解决这个问题,你必须告诉它从WEB-INF/lib 为这个包在weblogic.xml 中加载类:

          <prefer-application-packages>
              <package-name>org.opensaml.*</package-name>
          </prefer-application-packages>
      

      也许&lt;prefer-web-inf-classes&gt;true&lt;/prefer-web-inf-classes&gt; 也可以。

      【讨论】:

      • 100 万次。我不得不通过 Eclipse 编辑器编辑 weblogic.xml,结果看起来像这样:&lt;wls:container-descriptor&gt; &lt;wls:prefer-application-packages&gt; &lt;wls:package-name&gt;org.opensaml.*&lt;/wls:package-name&gt; &lt;/wls:prefer-application-packages&gt; &lt;/wls:container-descriptor&gt;
      【解决方案7】:

      java.lang.ClassNotFoundException 表示在类路径中找不到类。 可能是 log4j 的版本不兼容。 检查不同的 log4j 版本。

      【讨论】:

      • 如何判断是否兼容?
      【解决方案8】:

      添加 compile 'org.apache.logging.log4j:log4j-1.2-api:2.17.1' 然后它会自动工作

      【讨论】:

        【解决方案9】:

        我遇到了同样的问题,对我来说这解决了问题:
        右键项目->maven->更新项目

        【讨论】:

          【解决方案10】:

          在我的情况下,错误是由于我从类路径中删除的使用 log4j v 1.x 的一些依赖项造成的。因此,我按照Apache Migration guide 中的建议介绍了log4j-1.2-api 以将v 1.x 桥接到2.x:

          在我的build.gradle中引入这个依赖后,错误消失了:

          implementation 'org.apache.logging.log4j:log4j-1.2-api:2.17.+!!'

          【讨论】:

            猜你喜欢
            • 2020-04-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多