11

My maven project is like this and I have a quartz.properties file in /src/main/resources folder as shown below

my-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 using java -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 my pom.xml file to make an executable jar so that I can run it with java -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>
2
  • Really well formated question by the way. Commented Sep 14, 2015 at 6:43
  • Search SO before posting. Commented Sep 14, 2015 at 8:38

3 Answers 3

17

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.

Sign up to request clarification or add additional context in comments.

12 Comments

Thanks. Do I need maven-dependency-plugin as well? I have dependency on various other libraries as well some open source and some internal.
something 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 error java.lang.NoClassDefFoundError ----- Exception in thread "main" java.lang.NoClassDefFoundError: org/quartz/SchedulerException at java.lang.Class.getDeclaredMethods0(Native Method).
Only difference is - I also have maven-eclipse-plugin in my pom.xml file.
I do have a maven dependency for QuartzScheduler in my pom.xml.
May be this line is causing problem. I have something like this <classpathPrefix>dependency-jars/</classpathPrefix>
|
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

Comments

0

depending on what will end up in the jar file or what is required to run it it is probably not that easy. There is a good collection here: How can I create an executable JAR with dependencies using Maven?

I would add Spring-Boot to that list. They have created a maven plugin to achieve this including a classloader that can read jar files inside a jar file.

There is also the maven shade plugin. Depending on what you do that might just work or it may get cumbersome (if there are signed jars for example).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.