http://www.tuicool.com/articles/326JvaU
In this tutorial, we will show you how to use Maven build tool, One-JAR plugin to create a single Jar together with its dependency Jars into a single executable Jar file, so called fat Jar.
Tools used :
- Maven 3.1.1
- JDK 1.7
- Joda-time 2.5
1. Create a simple Java project
Create a Java project from the Maven quick start template.
$ mvn archetype:generate -DgroupId=com.mkyong.core.utils -DartifactId=dateUtils
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
The following files and folder structure will be created.
. |____dateUtils | |____pom.xml | |____src | | |____main | | | |____java | | | | |____com | | | | | |____mkyong | | | | | | |____core | | | | | | | |____utils | | | | | | | | |____App.java | | |____test | | | |____java | | | | |____com | | | | | |____mkyong | | | | | | |____core | | | | | | | |____utils | | | | | | | | |____AppTest.java
Make it support Eclipse.
$ mvn eclipse:eclipse
Imports the project into Eclipse IDE.
2. Update Pom.xml
Update pom.xml
to declare the jodatime dependencies. For output to a Jar
format, make sure the packaging tag is set to ‘jar’. Read the comments for self-explanatory.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mkyong.core.utils</groupId> <artifactId>dateUtils</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>dateUtils</name> <url>http://maven.apache.org</url> <properties> <jdk.version>1.7</jdk.version> <jodatime.version>2.5</jodatime.version> <junit.version>4.11</junit.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>${jodatime.version}</version> </dependency> </dependencies> <build> <finalName>dateutils</finalName> <plugins> <!-- download source code in Eclipse, best practice --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <version>2.9</version> <configuration> <downloadSources>true</downloadSources> <downloadJavadocs>false</downloadJavadocs> </configuration> </plugin> <!-- Set a compiler level --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> <!-- Make this jar executable --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.mkyong.core.utils.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> </project>
3. Get CurrentDate with JodaTime
Update the generated App.java
with the following content :
App.java
package com.mkyong.core.utils;
import org.joda.time.LocalDate;
public class App {
public static void main(String[] args) {
System.out.println(getLocalCurrentDate());
}
//Print current date with JodaTime
private static String getLocalCurrentDate() {
LocalDate date = new LocalDate();
return date.toString();
}
}
4. Jar File
Maven package the project to generate the final Jar file. A new dateutils.jar
is created in the $project/target
folder.
$ mvn package
List out the jar content.
$ jar tf target/dateutils.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/mkyong/
com/mkyong/core/
com/mkyong/core/utils/
com/mkyong/core/utils/App.class
META-INF/maven/
META-INF/maven/com.mkyong.core.utils/
META-INF/maven/com.mkyong.core.utils/dateUtils/
META-INF/maven/com.mkyong.core.utils/dateUtils/pom.xml
META-INF/maven/com.mkyong.core.utils/dateUtils/pom.properties
Try to run this Jar file.
$ java -jar dateutils.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/joda/time/LocalDate
at com.mkyong.core.utils.App.getLocalCurrentDate(App.java:14)
at com.mkyong.core.utils.App.main(App.java:9)
Caused by: java.lang.ClassNotFoundException: org.joda.time.LocalDate
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
... 2 more
Above is the expected error message, because the joda-time.jar
is missing.
5. One-Jar Example
Update pom.xml
to use One-Jar plugin, it will create a single Jar together with its dependency Jars.
pom.xml
<project> <build> <plugins> <!-- Includes the runtime dependencies --> <plugin> <groupId>org.dstovall</groupId> <artifactId>onejar-maven-plugin</artifactId> <version>1.4.4</version> <executions> <execution> <goals> <goal>one-jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <!-- One-Jar is in the googlecode repository --> <pluginRepositories> <pluginRepository> <id>onejar-maven-plugin.googlecode.com</id> <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url> </pluginRepository> </pluginRepositories> </project>
Package it again, two jars will be created in the “target” folder – dateUtils.jar
and dateUtils-one-jar.jar
.
$ mvn package
The dateUtils-one-jar.jar
is the final fat-jar you want, list out the jar content :
$ jar tf target/dateutils.one-jar.jar
META-INF/MANIFEST.MF
main/dateutils.jar
lib/joda-time-2.5.jar
com/
com/simontuffs/
com/simontuffs/onejar/
.version
OneJar.class
com/simontuffs/onejar/Boot$1.class
com/simontuffs/onejar/Boot$2.class
com/simontuffs/onejar/Boot$3.class
com/simontuffs/onejar/Boot.class
com/simontuffs/onejar/Handler$1.class
com/simontuffs/onejar/Handler.class
com/simontuffs/onejar/IProperties.class
com/simontuffs/onejar/JarClassLoader$1.class
com/simontuffs/onejar/JarClassLoader$2.class
com/simontuffs/onejar/JarClassLoader$ByteCode.class
com/simontuffs/onejar/JarClassLoader$FileURLFactory$1.class
com/simontuffs/onejar/JarClassLoader$FileURLFactory.class
com/simontuffs/onejar/JarClassLoader$IURLFactory.class
com/simontuffs/onejar/JarClassLoader$OneJarURLFactory.class
com/simontuffs/onejar/JarClassLoader.class
com/simontuffs/onejar/OneJarFile$1.class
com/simontuffs/onejar/OneJarFile$2.class
com/simontuffs/onejar/OneJarFile.class
com/simontuffs/onejar/OneJarURLConnection.class
src/
src/com/
src/com/simontuffs/
src/com/simontuffs/onejar/
src/OneJar.java
src/com/simontuffs/onejar/Boot.java
src/com/simontuffs/onejar/Handler.java
src/com/simontuffs/onejar/IProperties.java
src/com/simontuffs/onejar/JarClassLoader.java
src/com/simontuffs/onejar/OneJarFile.java
src/com/simontuffs/onejar/OneJarURLConnection.java
doc/
doc/one-jar-license.txt
One-Jar plugin puts the runtime dependencies in the lib
folder, for examplelib/joda-time-2.5.jar
, and the main jar in the main
folder, for examplemain/dateutils.jar
. In additional, it also creates many simontuffs classes to help loads the included Jars correctly.
Try to run the final fat-jar.
$ java -jar dateutils.one-jar.jar
2014-10-18
Done.
Download Source Code
Download – maven-one-jar-example.zip (6 KB)