【问题标题】:NoClassDefFoundError with gradle multi projectsNoClassDefFoundError 与 gradle 多项目
【发布时间】:2019-09-26 09:06:30
【问题描述】:

我已经在 java 中设置了一个 gradle 多项目。构建成功,但是当我尝试运行 JAR 时,抛出了 java.lang.NoClassDefFoundError。

这是我的项目结构:

.gradle/
authserver/
    build/
    src/main/java/fr/evywell/robserver/auth/
        Main.java
build/
common/
    build/
    src/main/java/fr/evywell/robserver/common/
gradle/
build.gradle
settings.gradle

然后是我的配置: settings.gradle(在根目录中)

rootProject.name = "robserver"

include 'authserver'
include 'common'

build.gradle(在根目录中)

subprojects {
    apply plugin: 'java'

    repositories {
        mavenCentral()
    }
}

build.gradle (IN common DIR)

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'io.netty', name: 'netty-all', version: '4.1.24.Final'
    compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
    compile group: 'org.javassist', name: 'javassist', version: '3.25.0-GA'
    compile group: 'com.jsoniter', name: 'jsoniter', version: '0.9.23'
}

build.gradle (IN authserver DIR)

apply plugin: 'application'

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'io.netty', name: 'netty-all', version: '4.1.24.Final'
    compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
    compile group: 'org.javassist', name: 'javassist', version: '3.25.0-GA'
    compile group: 'com.jsoniter', name: 'jsoniter', version: '0.9.23'
    compile project (':common')
}

mainClassName = 'fr.evywell.robserver.auth.Main'

jar {
    manifest {
        attributes 'Main-Class': 'fr.evywell.robserver.auth.Main'
    }
}

错误信息:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: fr/evywell/robserver/common/network/Server
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    at java.lang.Class.getMethod0(Class.java:3018)
    at java.lang.Class.getMethod(Class.java:1784)
    at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: fr.evywell.robserver.common.network.Server
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 7 more

错误消息说它在我的common 包中找不到类。 我不知道为什么,因为我在我的 authserver gradle 配置中使用了compile project (':common')

这里是命令:java -jar authserver/build/libs/authserver.jar

感谢您的帮助,祝您有愉快的一天!

【问题讨论】:

    标签: java gradle


    【解决方案1】:

    对我来说接下来的事情是:在 kotlin 中,我已经将 spring boot 插件应用于 root build.gradle 中的所有子项目{}

    我已经删除了而不是这个 apply(plugin = "org.springframework.boot") 来自根 build.gradle 并将此行应用于每个子项目而不是 common 模块

    【讨论】:

      【解决方案2】:

      我认为问题在于您正在创建的 JAR 不包含通过编译公共模块生成的类文件。尝试修改 authserver 模块的 jar 任务,以便包含编译公共模块的输出:

      jar {
           from project.sourceSets.main.allSource
           from project(":common").sourceSets.main.java.output
      
           manifest {
              attributes 'Main-Class': 'fr.evywell.robserver.auth.Main'
          }
      }
      

      【讨论】:

      • 当我添加这两行时,gradle build fail " > No such property: output for class: org.gradle.api.internal.file.DefaultSourceDirectorySet 可能的解决方案: outputDir " 即使使用 outputDir 而不是 output , 抛出同样的异常
      • OK - 请确认您使用的 gradle/gradle wrapper 的版本。
      • Gradle 5.6.2 - Kotlin:1.3.41 - Groovy:2.5.4 - JVP 1.8.0_222
      【解决方案3】:

      我使用影子插件构建了一个“胖罐子”。我不知道这是否是一个好习惯...

      感谢您的帮助!

      // authserver/build.gradle
      plugins {
          id 'com.github.johnrengelman.shadow' version '5.1.0'
          id 'java'
      }
      apply plugin: 'application'
      
      dependencies {
          testCompile group: 'junit', name: 'junit', version: '4.12'
          compile group: 'io.netty', name: 'netty-all', version: '4.1.24.Final'
          compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
          compile group: 'org.javassist', name: 'javassist', version: '3.25.0-GA'
          compile group: 'com.jsoniter', name: 'jsoniter', version: '0.9.23'
          compile project (':common')
      }
      
      mainClassName = 'fr.evywell.robserver.auth.Main'
      
      
      jar {
          manifest {
              attributes 'Main-Class': 'fr.evywell.robserver.auth.Main'
          }
      }
      
      

      【讨论】:

      • :common 库可能只是缺少入口点。 fat jar 与模块化设计相反。
      • 问题是通用包没有入口点,因为它只是实用程序类。我应该创建一个空的入口点还是什么?
      • 只是不要尝试运行它,就好像它有一个。
      猜你喜欢
      • 1970-01-01
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 2015-10-01
      相关资源
      最近更新 更多