gradle - how do I build a jar with a lib dir with other jars in it?
Solution 1
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
}
}
Solution 2
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.
Solution 3
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
Solution 4
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
Solution 5
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
phil swenson
Updated on July 05, 2022Comments
-
phil swenson almost 2 years
In gradle - how can I embed jars inside my build output jar in the lib directory (specifially the lib/enttoolkit.jar and lib/mail.jar)?
-
phil swenson almost 14 yearsI am on 0.9rc1. so tried your first suggestion. Pulled in all sorts of stuff I didn't want.....
-
phil swenson almost 14 yearscloser I think...problem is I need the jars in a lib directory. This pulls in the classes from the jars. I want lib/mail and lib/enttoolkit in the output jar
-
phil swenson almost 14 yearsthis works... sort of: sourceSets { main { java { srcDir "$wepTrunk/osgi/mycompany.osgi.server/src" } resources { srcDir "/Users/phil/dev/trunk/osgi/mycompany.osgi.server/lib" } } } it puts the jars from my /users/phil/dev/trunk/osgi/mycompany.osgi.server/lib in my output jar, but not in a "lib" directory. Any ideas how to get them in a lib dir?
-
Basil Musa almost 13 yearsI know this didn't answer the question, but a wonderful wonderful tip. Thanks lucas.
-
Sebastian Ganslandt almost 11 yearsGreat tip, but completely misses the pretty pretty specific question.
-
TheOperator about 8 yearsThis copies the libraries into the output directory, but not into the JAR file itself -- which was the question.
-
Thunderforge almost 8 yearsIf you want all the dependencies, you can also copy from
configurations.runtime
, which gives you the defaultcompile
dependencies, saving you the trouble of creating your ownextraLibs
configuration. -
naXa stands with Ukraine over 7 yearsError: Could not find method jar() for arguments [build_bndovev91pu8trwrdngc8qh7i$_run_closure5@3be2321e] on project ':app' of type org.gradle.api.Project.
-
naXa stands with Ukraine over 7 yearsThe link is not available due to "All Codehaus services have been terminated"
-
radistao over 7 yearspls, update the answer since "from" requires curly braces: see stackoverflow.com/a/4894308/907576
-
omikron about 7 yearsOk, I've done what is described here but I'm still getting
Exception in thread "main" java.lang.NoClassDefFoundError: com/rabbitmq/client/ConnectionFactory
. Should I setup classpath somehow? -
Tom almost 7 yearsA bit of an explanation about what this code does might help explain some of the specific bits?
-
Steve Pitchers over 5 years@Thunderforge To get all dependencies, I had to copy from
configurations.runtimeClasspath
rather thanconfigurations.runtime
, while avoiding the need for theextraLibs
definition. -
Lokesh Singal about 4 yearsWe just need to add resource after
srcDirs
processResources{ from(zipTree("src/main/resources/lib/local-jar-name.jar")) }