gradle - how do I build a jar with a lib dir with other jars in it?
In gradle - how can I embed jars inside my build output jar in the lib dir开发者_C百科ectory (specifially the lib/enttoolkit.jar and lib/mail.jar)?
If you have all the jars inside a directory (lets call it libs
) in your project, you only need this:
jar {
into('lib') {
from 'libs'
}
}
I guess it is more likely that these jars are dependencies of some sort. Then you could do it like this:
configurations {
// configuration that holds jars to copy into lib
extraLibs
}
dependencies {
extraLibs 'org.something:something-dep1:version'
extraLibs 'org.something:something-dep2:version'
}
jar {
into('lib') {
from configurations.extraLibs
}
}
Lifted verbatim from: http://docs.codehaus.org/display/GRADLE/Cookbook#Cookbook-Creatingafatjar
Gradle 0.9:
jar {
from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
Gradle 0.8:
jar.doFirst {
for(file in configurations.compile) {
jar.merge(file)
}
}
The above snippets will only include the compile dependencies for that project, not any transitive runtime dependencies. If you also want to merge those, replace configurations.compile with configurations.runtime.
EDIT: only choosing jars you need
Make a new configuration, releaseJars maybe
configurations {
releaseJars
}
Add the jars you want to that configuration
dependencies {
releaseJars group: 'javax.mail', name: 'mail', version: '1.4'
//etc
}
then use that configuration in the jar task outlined above.
simple:
task copyToLib( type: Copy ) {
into "$buildDir/libs/lib"
from configurations.runtime
}
jar { dependsOn copyToLib }
run it:
$ gradle jar
...
$ tree build/libs
build/libs
├── your-project-0.0.1.BUILD-SNAPSHOT.jar
└── lib
├── akka-actor-2.0.jar
├── akka-camel-2.0.jar
├── ... ... ...
├── spring-expression-3.1.0.RELEASE.jar
└── zmq-2.1.9.jar
1 directory, 46 files
I also needed to do something similar and wasn't quite able to get what Guus and stigkj suggested working, but got close enough with their help to get this working (Guus' example blew up on the dependencies { compile { extendsFrom myLibs }}
closure for me.
apply plugin: 'groovy'
repositories {
mavenCentral()
}
configurations {
// custom config of files we want to include in our fat jar that we send to hadoop
includeInJar
}
dependencies {
includeInJar 'org.codehaus.groovy:groovy:1.8.6'
configurations.compile.extendsFrom(configurations.includeInJar)
}
jar {
into('lib') {
println "includeInJar: " + configurations.includeInJar.collect { File file -> file }
from configurations.includeInJar
}
}
Then running gradle jar
and examining the created jar gives me this output, showing that I get the jar file to have groovy as well as all jars that it's dependent on inside the "fat jar":
% gradle jar
includeInJar: [/Users/tnaleid/.gradle/caches/artifacts-8/filestore/org.codehaus.groovy/groovy/1.8.6/jar/553ca93e0407c94c89b058c482a404427ac7fc72/groovy-1.8.6.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/antlr/antlr/2.7.7/jar/83cd2cd674a217ade95a4bb83a8a14f351f48bd0/antlr-2.7.7.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm/3.2/jar/9bc1511dec6adf302991ced13303e4140fdf9ab7/asm-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-tree/3.2/jar/cd792e29c79d170c5d0bdd05adf5807cf6875c90/asm-tree-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-commons/3.2/jar/e7a19b8c60589499e35f5d2068d09013030b8891/asm-commons-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-util/3.2/jar/37ebfdad34d5f1f45109981465f311bbfbe82dcf/asm-util-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-analysis/3.2/jar/c624956db93975b7197699dcd7de6145ca7cf2c8/asm-analysis-3.2.jar]
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar
BUILD SUCCESSFUL
Total time: 3.387 secs
% jar tvf build/libs/gradletest.jar
0 Mon Mar 12 11:40:00 CDT 2012 META-INF/
25 Mon Mar 12 11:40:00 CDT 2012 META-INF/MANIFEST.MF
0 Mon Mar 12 11:40:00 CDT 2012 lib/
5546084 Mon Mar 05 13:13:32 CST 2012 lib/groovy-1.8.6.jar
445288 Mon Mar 05 13:13:38 CST 2012 lib/antlr-2.7.7.jar
43398 Mon Mar 05 13:13:40 CST 2012 lib/asm-3.2.jar
21878 Mon Mar 05 13:13:40 CST 2012 lib/asm-tree-3.2.jar
33094 Mon Mar 05 13:13:40 CST 2012 lib/asm-commons-3.2.jar
36551 Mon Mar 05 13:13:40 CST 2012 lib/asm-util-3.2.jar
17985 Mon Mar 05 13:13:40 CST 2012 lib/asm-analysis-3.2.jar
Below code could be tried. It depends on the jar task and is of Type Jar
task createJobJar(dependsOn:jar,type:Jar) {
manifest {
attributes(
"Implementation-Title": 'Job '
,"Implementation-Version": version
)
}
classifier 'job'
destinationDir new File("$buildDir")
into('libs'){
from configurations.compile
}
into('classes'){
from "$buildDir/classes"
}
into('resources'){
from "$projectDir/src/main/resources"
}
into('scripts'){
from "$projectDir/src/main/scripts"
}
}
The above code would pack different content inside different directories. Tested on gradle 2.2
I needed to the same thing you asked, and used this method. you may not need a custom configuration declaration, but i needed to separate the locally used jar files from those declared in a super-build file.
configurations{
//declare custom config if necessary, otherwise just use compile
myLibs
}
dependencies {
//add lib/*.jar files to myLibs
myLibs fileTree(dir: 'lib', include: '*.jar')
compile {
//set compile configuration to extend from myLibs
extendsFrom myLibs
}
}
// task to copy libs to output/lib dir
task copyToLib(type: Copy) {
into "$buildDir/output/lib"
from configurations.myLibs
}
jar {
//include contents of output dir
from "$buildDir/output"
manifest {
//...
}
}
//set build task to depend on copyToLib
build.dependsOn(copyToLib)
I had the same problem. I solved it like this:
Copy the files into the lib folder with copyToLib and reference the dependency with the Class-Path
ext.mainClass = 'test.main'
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.google.code.gson:gson:2.8.2'
//....
}
jar {
from "$buildDir/libs/lib"
manifest {
attributes 'Main-Class': 'test.main',
'Class-Path': configurations.compile.collect { 'lib/'+it.getName() }.join(' ')
}
}
task copyToLib(type: Copy) {
into "$buildDir/libs/lib"
from configurations.compile
}
build.dependsOn(copyToLib)
In my case I needed to include a contents of the root project Jar into subproject Jar. So, to make it work, one can use this template:
jar{
manifest{
attributes 'Main-Class':'<main class>'
}
def conf= configurations.find {it.name.equals('compile') }
File jar= conf.files.find {it.name.contains('<name or part of the name of produced Jar>')}
FileTree fileTree=zipTree(jar)
from fileTree
}
My example:
jar{
manifest{
attributes 'Main-Class':'alexiy.jace.Jace'
}
description='Make a runnable API Jar'
def conf= configurations.find {it.name.equals('compile') }
File tools= conf.files.find {it.name.contains('Tools')}
FileTree fileTree=zipTree(tools)
from fileTree
}
Here's how I managed to achieve this build setting using Gradle. This will build your app into a Jar, copy the library jars generated into the libs directory under build/libs and also configure classpath to include the jars in the created build/libs/libs directory.
plugins {
id 'application'
}
group 'org.pkg'
version '1.0-SNAPSHOT'
ext.mainClass = 'org.pkg.MainClass'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile group: 'junit', name: 'junit', version: '4.12'
implementation group: 'com.mchange', name: 'c3p0', version: '0.9.5.5'
}
task copyToLib(type: Copy) {
into "$buildDir/libs/libs"
// configurations.runtimeClasspath includes maven jars
from configurations.runtimeClasspath
}
def archiveVersion = "1.0.0"
task uberJar(type: Jar) {
archiveClassifier = 'uber'
from sourceSets.main.output
// include the copy task
dependsOn(copyToLib)
// use onfigurations.runtimeClasspath to collect all the jars
manifest {
attributes(
'Class-Path': configurations.runtimeClasspath.collect { 'libs/' + it.getName() }.join(' '),
'Main-Class': 'org.pkg.MainClass',
"Implementation-Title": "Gradle",
"Implementation-Version": archiveVersion
)
}
}
task <taskname>(type: Jar) {
archiveName 'nameofjar.jar'
doFirst {
manifest {
attributes 'Class-Path': configurations.compile.files.collect{ project.uri(it) }.join(' ')
}
}
}
精彩评论