jychan
jychan

Reputation: 1011

how to copy the dependencies libraries JARs in gradle

I got a runnable jar with this build.gradle

    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.+'
        )
    }

but it run failed, because the dependencies jars can't find.

and then I add this code:

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

but nothing change. I can't find the folder output/libs.

how can I copy the dependencies libs jars to a specified folder or path?

Upvotes: 49

Views: 60052

Answers (8)

Shandilya
Shandilya

Reputation: 103

For Gradle 7.4 with Groovy:

configurations {
    externalLib.extendsFrom(implementation)
}

task copyLibs(type: Copy){
    from configurations.externalLib{
        into '<dest-dir-name>'

        exclude('<if any jars need to be excluded>')
    }
}

Upvotes: 1

Fizz Areh
Fizz Areh

Reputation: 97

The problem with all the previous answers is that they only collect dependencies from one configuration. To get ALL of the dependencies, you should use this:

task saveDependencies(type: Copy){
    configurations.each {
        if (it.isCanBeResolved())
            from it into "gradle_dependencies"
    }
    from buildscript.configurations.classpath into "gradle_dependencies"
}

Upvotes: 2

Jason Slobotski
Jason Slobotski

Reputation: 1456

As of at least Gradle 5.6.4 you'll want to do something closer to this.

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) }
    }
}

Upvotes: 1

lainatnavi
lainatnavi

Reputation: 1613

The java plugin can pack a jar with dependencies and there's no need for the application plugin. A task like the following would do:

task buildWithDeps(type: Jar) {
    manifest {
        attributes "Main-Class": "com.test.HelloWorld"
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

Upvotes: 1

Nikita Tukkel
Nikita Tukkel

Reputation: 2305

Since Gradle 6.0 it is:

tasks {
    val deps by registering(Copy::class) {
        from(configurations.runtimeClasspath)
        into("build/deps")
    }
}

Upvotes: 8

xielingyun
xielingyun

Reputation: 820

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)

Upvotes: 48

Martin Andersson
Martin Andersson

Reputation: 19573

I find the application plugin way too cumbersome and too verbose in its output. Here's how I finally got a setup I was happy with, i.e., create a distribution zip file with dependency jars in subdirectory /lib and add all dependencies to Class-Path entry in the manifest file:

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
}

Hosted as a gist here.

The result can be found in build/distributions and the unzipped contents look like this:

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

Contents of MyJarFile.jar#META-INF/MANIFEST.mf:

Manifest-Version: 1.0
Main-Class: com.somepackage.MainClass
Class-Path: lib/commons-lang3-3.3.2.jar

Upvotes: 19

Benjamin Muschko
Benjamin Muschko

Reputation: 33436

The application plugin requires you to set the main class name like this:

mainClassName = "com.test.HelloWorld"

You will need to add that to your build script. Keep in mind that if you try to run your application with the java command you will also need to set the classpath with -cp.

The application plugin simplifies this process by providing the task distZip. If you run that task you a full distribution is created for you under build/distributions. The distribution contains start scripts and all dependencies. The generated start scripts already set the classpath for you so you don't have to deal with it anymore.

Upvotes: 1

Related Questions