Gradle 为具有 implementation 关键字的依赖项抛出 NoClassDefFoundError

Gradle throws NoClassDefFoundError for dependencies with implementation keyword

我正在使用 Intellij Idea,gradlew 版本 6.8。

每当我为 build.gradle 中的依赖项指向 implementation 关键字时 - 我得到(具有 gson 依赖项的示例)此异常:

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gson
        at com.epam.adnocove.search.job.EmailVerifier.<clinit>(EmailVerifier.java:19)
        at com.epam.adnocove.search.job.UserIndexPipeline.<clinit>(UserIndexPipeline.java:31)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:636)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
        ... 2 more 

我的build.gradle文件:

plugins {
    id 'java'
}

group 'com.epam.adnocove'
version '1.0'

repositories {
    mavenCentral()
}

jar {
    manifest {
        attributes 'Main-Class': 'Program'
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }

    exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}

dependencies {
    implementation 'com.google.code.gson:gson:2.8.2'
    testImplementation 'junit:junit:4.12'
}

如果我输入 compile 而不是 implementation - 一切都按预期进行。但是,如果我不想传递依赖怎么办。为什么 gradle 没有将我的依赖项放到我的 jar 中?

问题是默认情况下仅与 java 插件一起构建 - Gradle 不会将依赖项打包到 jar - 因此我们得到一个异常。

解决方法: 我们可以使用 fat jars(by separate task), or use java application plugin 来创建 OS 特定的启动应用程序,这些应用程序可以 运行 构建 jar。