47

我用这个 build.gradle 得到了一个可运行的 jar

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

manifest.mainAttributes("Main-Class" : "com.test.HelloWorld")

repositories {
    mavenCentral()
}

dependencies {
    compile (
        'commons-codec:commons-codec:1.6',
        'commons-logging:commons-logging:1.1.1',
        'org.apache.httpcomponents:httpclient:4.2.1',
        'org.apache.httpcomponents:httpclient:4.2.1',
        'org.apache.httpcomponents:httpcore:4.2.1',
        'org.apache.httpcomponents:httpmime:4.2.1',
        'ch.qos.logback:logback-classic:1.0.6',
        'ch.qos.logback:logback-core:1.0.6',
        'org.slf4j:slf4j-api:1.6.0',
        'junit:junit:4.+'
    )
}

但它运行失败,因为找不到依赖项 jar。

然后我添加以下代码:

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

但没有任何改变...我找不到文件夹输出/库...

如何将依赖项库 jar 复制到指定的文件夹或路径?

4

7 回答 7

46

Add:

build.dependsOn(copyToLib)

When gradle build runs, Gradle builds tasks and whatever tasks depend on it (declared by dependsOn). Without setting build.dependsOn(copyToLib), Gradle will not associate the copy task with the build task.

So:

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

manifest.mainAttributes('Main-Class': 'com.test.HelloWorld')

repositories {
    mavenCentral()
}

dependencies {
    compile (
        'commons-codec:commons-codec:1.6',
        'commons-logging:commons-logging:1.1.1',
        'org.apache.httpcomponents:httpclient:4.2.1',
        'org.apache.httpcomponents:httpclient:4.2.1',
        'org.apache.httpcomponents:httpcore:4.2.1',
        'org.apache.httpcomponents:httpmime:4.2.1',
        'ch.qos.logback:logback-classic:1.0.6',
        'ch.qos.logback:logback-core:1.0.6',
        'org.slf4j:slf4j-api:1.6.0',
        'junit:junit:4.+'
    )
}

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

build.dependsOn(copyToLib)
于 2013-10-08T06:03:44.467 回答
18

我发现应用程序插件在其输出中过于繁琐且过于冗长。这是我最终获得满意设置的方式,即在子目录中创建一个包含依赖 jar 的分发 zip 文件,/lib并将所有依赖Class-Path项添加到清单文件中的条目:

apply plugin: 'java'
apply plugin: 'java-library-distribution'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.2'
}

// Task "distZip" added by plugin "java-library-distribution":
distZip.shouldRunAfter(build)

jar {
    // Keep jar clean:
    exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'

    manifest {
        attributes 'Main-Class': 'com.somepackage.MainClass',
                   'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
    }
    // How-to add class path:
    //     http://stackoverflow.com/questions/22659463/add-classpath-in-manifest-using-gradle
    //     https://gist.github.com/simon04/6865179
}

在这里作为要点托管。

结果可以在 中找到,build/distributions解压后的内容如下所示:

lib/commons-lang3-3.3.2.jar
MyJarFile.jar

内容MyJarFile.jar#META-INF/MANIFEST.mf

清单版本:1.0
主类:com.somepackage.MainClass
类路径:lib/commons-lang3-3.3.2.jar

于 2015-03-03T06:06:47.560 回答
7

从 Gradle 6.0 开始,它是:

tasks {
    val deps by registering(Copy::class) {
        from(configurations.runtimeClasspath)
        into("build/deps")
    }
}
于 2019-11-15T18:42:15.077 回答
1

应用程序插件要求您像这样设置主类名称:

mainClassName = "com.test.HelloWorld"

您需要将其添加到您的构建脚本中。请记住,如果您尝试使用该java命令运行您的应用程序,您还需要使用-cp.

应用程序插件通过提供任务distZip简化了这个过程。如果您运行该任务,则会在build/distributions. 该发行版包含启动脚本和所有依赖项。生成的启动脚本已经为您设置了类路径,因此您不必再处理它了。

于 2013-02-13T20:04:16.863 回答
1

java插件可以打包一个带有依赖项的jar,并且不需要该application插件。像下面这样的任务会做:

task buildWithDeps(type: Jar) {
    manifest {
        attributes "Main-Class": "com.test.HelloWorld"
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}
于 2020-03-13T11:25:45.183 回答
0

所有先前答案的问题在于它们仅从一个配置中收集依赖项。要获取所有依赖项,您应该使用以下命令:

task saveDependencies(type: Copy){
    configurations.each {
        if (it.isCanBeResolved())
            from it into "gradle_dependencies"
    }
    from buildscript.configurations.classpath into "gradle_dependencies"
}
于 2022-01-06T17:52:04.960 回答
0

至少从 Gradle 5.6.4 开始,您会想要做一些更接近此的事情。

dependencies {
    implementation 'my.group1:my-module1:0.0.1'
    implementation 'my.group2:my-module2:0.0.1'
}

jar {
    from {
        configurations.compileClasspath.filter { it.exists() }.collect { it.isDirectory() ? it : zipTree(it) }
    }
}
于 2020-10-15T14:53:28.620 回答