Java 代码对外部库中的类抛出 NoClassDefFoundError

标签 java maven gradle

我有一个 Maven 项目,其中包含一个使用 gradle 作为 pom 依赖项创建的 jar。 在包含 Jar 的代码中,我引用了 log4j logmanager。 当我尝试访问外部 jar 中的方法时,它会在外部 jar 内的类所引用的 logmanager 上抛出 java.lang.NoClassDefFoundError 。

外部 jar 的 build.gradle 是:

plugins {
    id 'java'
}

group 'com.somecompany.somethingelse'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {

    implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.13.0'
    implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.13.0'

}

我使用 gradle clean assemble 构建 jar

我使用 mvn install:install-file 将此 jar 本地安装到 .m2 中,然后在使用应用程序的 pom 中具有它的依赖项。

我不太确定这里发生了什么。

外部Jar类代码

package com.company.something;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public abstract class MyClass{

     private static Logger logger = LogManager.getLogger();

     public static String myMethod(String someInput){
         logger.info("entered myMethod");
         ......some code goes here.....

     }

}

Jar 消费类代码

import com.company.something.MyClass;

public class consumingClass{

   public String consumingMethod(){
      MyClass.myMethod("someinput");
      return "something";
    }
}

最佳答案

当您使用mvn install:install-file时,您正在安装jar文件并使用普通Maven为其创建默认pom。如果您不执行任何其他操作,pom 将不会包含任何传递依赖项。毕竟,Maven 只看到一个 jar 文件,对周围的 Gradle 脚本一无所知。这就是为什么它在运行时失败,因为库(“外部”)pom 中缺少 Log4J 依赖项。

您应该做的是使用 Maven Publish Plugin for Gradle为您的库创建合适的 pom。通过添加以下内容来做到这一点:

plugins {
    id 'maven-publish'
}

publishing {
    publications {
        myLibrary(MavenPublication) {
            from components.java
        }
    }
}

然后,您可以使用 gradlepublishToMavenLocal 将包含完整 pom 的 jar 文件上传到本地 .m2 存储库。

此外,ysakhno's answer关于编译类路径上不需要 log4j-core 的部分是正确的 - 这只是不好的做法。相反,您应该删除它并使使用项目将其添加为显式依赖项,将配置从implementation更改为仅运行时。两种方法都可以,具体取决于您希望 Log4j 与库的耦合程度。

我还认为在库中使用 Log4J2 API 是完全可以的,即使它可以在使用许多不同日志记录实现的项目中使用。毕竟,将 Log4J2 API 绑定(bind)到 SLF4J 和反之亦然一样容易。两者都很受欢迎,而且都是非常好的选择。

关于Java 代码对外部库中的类抛出 NoClassDefFoundError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60103216/

相关文章:

java - 如何在按键时重置处理 Canvas ?

JavaFX:在按键事件上获取 TableView 中的目标行索引

java - Spring工具套件IDE

maven - 是否必须指定 maven-failsafe-plugin 才能运行集成测试?

java - 在 Maven 中,如何将 JUnit 测试用例作为测试套件的一部分而不是单独运行?

java - 如何替换 gradle 中依赖项的依赖项?

google-app-engine - Google App Engine:如何为iOS生成发现文档(渐进式构建)?

java - 小程序 java.io.FilePermission 异常

java - 如何解决 "Could not find artifact com.ohadr:authentication-flows"?

groovy - 如何运行由 gradle 中的插件创建的任务