How to make an executable jar using maven?
Solution 1
You can configure maven jar plugin to achieve this.
Try adding following just above dependencies section:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mycompany.app.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Here, <addClasspath>true</addClasspath>
will add classpath entries to the manifest of your jar, so as long as you have those jars in same directory, your application will run fine.
You can customize the library path with, for example, <classpathPrefix>lib/</classpathPrefix>
. It means your libraries should be placed in relative /lib
directory.
You can also use maven dependency plugin if you want to automatically copy your libraries to output directory.
Solution 2
Actually you'll just need to add
<packaging>jar</packaging>
to your header, In other words:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.host.domain</groupId>
<artifactId>DataPlatform</artifactId>
<version>4.2.8-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>abc</artifactId>
<version>1.0.0</version>
<!-- This is where the magic happens -->
<packaging>jar</packaging>
Then when you invoke on the command line make sure you include the fully qualified name of your class, like this:
java -cp NameOfFile.jar com.mycompany.app.App
The advantage of this is that you can multiple class files with main()
methods that can be executed in one .jar file.
You can also include the suggestion of @Amila so you don't have to include the name when executing the jar, but you'll have to use this syntax instead:
java -jar NameOfFile.jar
user1950349
Updated on June 23, 2022Comments
-
user1950349 almost 2 years
My maven project is like this and I have a
quartz.properties
file in/src/main/resources
folder as shown belowmy-app |-- pom.xml `-- src |-- main | |-- java | | `-- com | | `-- mycompany | | `-- app | | `-- App.java | `-- resources | `-- quartz.properties `-- test |-- java `-- com `-- mycompany `-- app `-- AppTest.java
Now I want to make an executable jar using maven so that I can run it like this
java -jar abc.jar
. Below is my main method code which works fine in my laptop in my eclipse IDE but I want to run it on my ubuntu machine usingjava -jar
command:public static void main(String[] args) { StdSchedulerFactory factory = new StdSchedulerFactory(); try { factory.initialize(App.class.getClassLoader().getResourceAsStream("quartz.properties")); Scheduler scheduler = factory.getScheduler(); scheduler.start(); } catch (SchedulerException ex) { System.out.println("error= " + ExceptionUtils.getStackTrace(ex)); } }
And here is my
pom.xml
file as of now. What changes I need to have in mypom.xml
file to make an executable jar so that I can run it withjava -jar
?<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.host.domain</groupId> <artifactId>DataPlatform</artifactId> <version>4.2.8-RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>abc</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.3.1</version> </dependency> </dependencies> </project>
-
user1950349 over 8 yearsThanks. Do I need
maven-dependency-plugin
as well? I have dependency on various other libraries as well some open source and some internal. -
user1950349 over 8 yearssomething is weird, I tried your way and I did
mvn clean install
which generated a jar file and I used that file and ran it and I got this errorjava.lang.NoClassDefFoundError
-----Exception in thread "main" java.lang.NoClassDefFoundError: org/quartz/SchedulerException at java.lang.Class.getDeclaredMethods0(Native Method)
. -
user1950349 over 8 yearsOnly difference is - I also have
maven-eclipse-plugin
in my pom.xml file. -
user1950349 over 8 yearsI do have a maven dependency for QuartzScheduler in my pom.xml.
-
user1950349 over 8 yearsMay be this line is causing problem. I have something like this
<classpathPrefix>dependency-jars/</classpathPrefix>
-
Amila over 8 yearsthat line means, you should place all your library jars in a subdirectory named "dependency-jars". have you done so?
-
user1950349 over 8 yearsI just added it but I am getting above error. I don't know why.
-
user1950349 over 8 yearsDo I need to use
maven-shade-plugin
here? -
Amila over 8 yearsNo need to use shade plugin if your libraries are correctly located. Exact your jar and see MANIFEST.MF file has a line similar to: Class-Path: dependency-jars/lib1.jar dependency-jars/lib2.jar
-
user1950349 over 8 yearsYes I do see that jar. I started using lib so I see this -
lib/quartz-2.2.1.jar
andlib/quartz-jobs-2.2.1.jar
-
Amila over 8 years@user1950349 can you update your question with your output directory structure and the way you're executing your program?
-
user1950349 over 8 yearsLet us continue this discussion in chat.