Gradle – Create a Jar file with dependencies

In this tutorial, we will show you how to use Gradle build tool to create a single Jar file with dependencies.

Tools used :

  1. Gradle 2.0
  2. JDK 1.7
  3. Logback 1.1.2

1. Project Directory

Create following project folder structure :

gradle-hello-folder

By default, Gradle is using the standard Maven project structure.

  1. ${Project}/src/main/java/
  2. ${Project}/src/main/resources/
  3. ${Project}/src/test/java/

2. Java Files

A single Java file to print out the current date time, and logs the message with logback.

DateUtils.java

package com.mkyong;

import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DateUtils{
	
	private static final Logger logger = LoggerFactory.getLogger(DateUtils.class);
	
	public static void main(String[] args) {
		
		logger.debug("[MAIN] Current Date : {}", getCurrentDate());
		System.out.println(getCurrentDate());
	}
	
	private static Date getCurrentDate(){
		return new Date();
	}
	
}
logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
	  <layout class="ch.qos.logback.classic.PatternLayout">

		<Pattern>
			%-5level %logger{36} - %msg%n
		</Pattern>

	  </layout>
	</appender>

	<root level="debug">
	  <appender-ref ref="STDOUT" />
	</root>

</configuration>

3. build.gradle

A build.gradle sample to create a Jar file along with its logback dependencies.

build.gradle

apply plugin: 'java'
apply plugin: 'eclipse'

version = '1.0'
sourceCompatibility = 1.7
targetCompatibility = 1.7

//create a single Jar with all dependencies
task fatJar(type: Jar) {
	manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',  
        	'Implementation-Version': version,
        	'Main-Class': 'com.mkyong.DateUtils'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

//Get dependencies from Maven central repository
repositories {
    mavenCentral()
}

//Project dependencies
dependencies {
	compile 'ch.qos.logback:logback-classic:1.1.2'
}

4. Create a Jar File

Clean the project.


$ gradle clean 

Run the Gradle fatJar task.


$ gradle fatJar 

:compileJava
:processResources
:classes
:fatJar

BUILD SUCCESSFUL

Total time: 6.4 secs

The Jar is created under the $project/build/libs/ folder.

gradle-build-folder

5. Run It

Run it – java -jar hello-all-1.0.jar.


$Project\build\libs> java -jar hello-all-1.0.jar
16:22:13,249 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
16:22:13,249 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
//...

DEBUG com.mkyong.DateUtils - [MAIN] Current Date : Wed Aug 27 16:22:13 SGT 2014
Wed Aug 27 16:22:13 SGT 2014

Done.

Download Source Code

Download It – gradle-create-single-jar.zip (1.4 KB)

References

  1. Gradle : Jar Task
  2. Wikipedia : Gradle

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
16 Comment threads
4 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
18 Comment authors
CHRIS FOUTSthomasAdam M. EricksonJ Jnajeeb Recent comment authors
newest oldest most voted
Caspar
Guest
Caspar

Doesn’t work. I get “no main manifest attribute, in gradle-create-single-jar-all-1.0.jar” with the uploaded example.

Java Developer
Guest
Java Developer

Thanks for the short tutorial. This seems to be way to complicated as compared to maven. Since we just need to use a assembly or onejar plugin.

???
Guest
???

It’s really useful for me, thanks

Ruslan Ibragimov
Guest
Ruslan Ibragimov

I think this is much better:http://www.gradle.org/docs/current/userguide/application_plugin.html
just add this lines to build.gradle:

apply plugin: ‘application’
mainClassName = “com.mkyong.DateUtils”

and then run gradle task:

$ gradle distZip

It’s better, because:
1. This is plugin and your build.gradle much cleaner.
2. This distribute only runtime deps, not compile and test.
3. This will be maintained by plugin contributers.

Jason Zwolak
Guest
Jason Zwolak

mkyong, your example only works in some cases. I used it on my project with a dependency on javaee and jersey and I ended up with a jar with multiple entries with the same name… and Java doesn’t like it when running in a webstart application. But thanks anyway, I’ve gotten a ton of useful information from you blog in the past!!! When I see it in a Google search I think “ah, that’s good, I trust this guy” 😉

Matt
Guest
Matt

java.lang.StackOverflowError (no error message)

Guest
Guest
Guest

After hours of google searching, you were the saving grace! Thank you so much

Leo
Guest
Leo

Is there a way to store all the dependencies in one folder in jar, e.g. /libs ?

Guason
Guest
Guason

I use the shadowjar!!!

shadowJar {
configurations = [project.configurations.compile]
classifier = null
baseName = ‘MyNewJARFileName’
version = null
}

Toni
Guest
Toni

Great Job!

Guason
Guest
Guason

group ‘br.com.teste.teste’ version ‘1.0’ apply plugin: ‘java’ apply plugin: ‘application’ mainClassName = “br.com.teste.Main” sourceCompatibility = 1.8 targetCompatibility = 1.8 apply plugin: ‘com.github.johnrengelman.shadow’ shadowJar { configurations = [project.configurations.compile] classifier = null baseName = ‘MyTesteJARFilenameHere’ version = null } buildscript { repositories { jcenter() } dependencies { classpath ‘com.github.jengelman.gradle.plugins:shadow:2.0.2’ } } repositories { mavenCentral() } task execute(type: JavaExec) { main = “br.com.teste.Main” classpath = sourceSets.main.runtimeClasspath systemProperties System.getProperties() args System.getProperty(“exec.args”, “”).split() } sourceSets { main { java { srcDirs = [‘src/main/java’] } resources { srcDirs = [‘src/main/resources’] } } test { java { srcDirs = [‘src/test/java’] } resources { srcDirs = [‘src/test/resources’] }… Read more »

Dirk Hoffmann
Guest
Dirk Hoffmann

For me this did work better:


jar {
manifest {
attributes "Main-Class": application.mainClassName
}

from {
// filters only existing and non-empty dirs
sourceSets.main.runtimeClasspath
.filter { (it.isDirectory() && it.listFiles().length > 0) || it.isFile() }
.collect { it.isDirectory() ? it : zipTree(it) }

}
}

J J
Guest
J J

For me at first it didn’t work. I spent ages trying to figure out why it wasn’t working and eventually I realised I was supposed to do “gradle fatJar” not “gradle build” – it does say it in the tutorial but perhaps like many others I am often in too much of a hurry for my own good. Thanks.

Adam M. Erickson
Guest
Adam M. Erickson

You always give just enough to force us to use our heads to figure out the rest. Thank you!

For people that are adding signed third part jars. Make sure to add this exclude line in the gradle.build file!

exclude ‘META-INF/*.RSA’, ‘META-INF/*.SF’,’META-INF/*.DSA’

`Works perfectly. Thank you Mkyong

https://stackoverflow.com/questions/37848553/error-in-executing-the-generated-jar-file/37848829

thomas
Guest
thomas

Thanks for the solution. Really helpful.

CHRIS FOUTS
Guest
CHRIS FOUTS

What if you have a LOT of dependencies, but only what to include certain ones, and NOT all of them? I’ve seen examples where that show including one of many dependencies, but not several of many (but not all) dependencies.