jar 中的 NoClassDefFoundError 但 Intellij 中没有

NoClassDefFoundError in jar but not in Intellij

我正在尝试 运行 具有依赖项的 jar。该应用程序 运行 在 Intellij 中很好,但是当我尝试 运行 我得到的罐子时:

>> java -jar test-0.1.0.jar
Exception in thread "main" java.lang.NoClassDefFoundError: com/atlassian/httpclient/apache/httpcomponents/DefaultHttpClient
        at com.atlassian.jira.rest.client.internal.async.AsynchronousHttpClientFactory.createClient(AsynchronousHttpClientFactory.java:53)
        at com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory.create(AsynchronousJiraRestClientFactory.java:35)
        at com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory.createWithBasicHttpAuthentication(AsynchronousJiraRestClientFactory.java:42)
        at Main.main(Main.java:19)
Caused by: java.lang.ClassNotFoundException: com.atlassian.httpclient.apache.httpcomponents.DefaultHttpClient
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 4 more 

我的 build.gradle 看起来像这样:

group 'test'
version '1.0-SNAPSHOT'

task wrapper(type: Wrapper) {
  gradleVersion = '2.9'
  distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'application'

sourceCompatibility = 1.8

mainClassName = "Main"

repositories {
    mavenCentral()
    maven {
        url 'https://maven.atlassian.com/content/repositories/atlassian-public/'
    }
}

jar {
    baseName = 'test'
    version =  '0.1.0'

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

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

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'

    compile 'com.atlassian.jira:jira-rest-java-client-parent:4.0.0'
    compile 'com.atlassian.jira:jira-rest-java-client-core:4.0.0'
    compile 'com.atlassian.jira:jira-rest-java-client-api:4.0.0'
    compile 'com.atlassian.jira:jira-rest-java-client-plugin:3.0.0'
    compile 'com.atlassian.fugue:fugue-parent:2.6.1'
    compile 'com.atlassian.fugue:fugue:2.6.1'
}

我也试过在每个编译子句中添加 transitive=true 但没有用。

你需要set CLASSPATH

The class path is the path that the Java runtime environment searches for classes and other resource files. The class search path (more commonly known by the shorter name, "class path") can be set using either the -classpath option when calling a JDK tool (the preferred method) or by setting the CLASSPATH environment variable. The -classpath option is preferred because you can set it individually for each application without affecting other applications and without other applications modifying its value.

更新:

默认情况下,Gradle 不会将依赖项复制到构建文件夹或将其包含到 jar 中。解决依赖问题的三种方法:

  1. 分别下载并放入相应目录。
  2. 使用插件构建fat jar。类似于 shadow.
  3. 添加到 build.gradle 将依赖项复制到构建文件夹的任务。

例如

task copyDependencies(type: Copy) {
    into "$buildDir/libs"
    from configurations.runtime
}