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?
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)
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
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.