How do I package and run a simple command-line application with dependencies using maven?
Asked Answered
I

5

21

I am brand new to both java and to maven, so this is likely very simple.

If I follow the maven2 hello world instructions here:

http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

everything works OK. If I then alter pom.xml to bring in a dependency from a remote repository, the files for this dependency get stored in ~/.m2/repository/new-dependency/.

Using the syntax in the hello world instructions to run the application requires that I add the absolute path to the dependency to my classpath (either by setting the environment variable or via the command line switch):

java -cp target/my-app-1.0-SNAPSHOT.jar:/.../.m2/.../new-dependency.jar com.mycompany.app.App

This will obviously get unwieldy quickly :)

I suspect that this is not the usual way of running a java program and that I just need to read more about .jar files, but while I am doing so I would appreciate any tips on how to do this properly.

I am not using an IDE, btw. vim from the command line.

Thanks!

Mike.

Isidroisinglass answered 16/5, 2011 at 22:11 Comment(0)
H
19

You can make a jar executable by adding the Main-Class attribute to its manifest file. In Maven this is done by the archiver plugin. To add the Main-Class attribute, add this to your pom.xml:

 <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>

You can now run your jar with the command: java -jar myjar.jar or by double clicking on it (not available in all platforms).

Hilaryhilbert answered 16/5, 2011 at 22:34 Comment(2)
To make this solution work I needed to add classpathMavenRepositoryLayout=true and classpathPrefix=/home/.../.m2/repository/ to the manifest section also because default behavior is to just put the name of the jar in the manifest (no reference to it's location in the filesystem).Isidroisinglass
Yes, the default behaviour expects the dependecies to be on the same directory of your main jar. Since you have the dependencies on your local repo, with your solution, the jar can be run from anywhere in your system.Hilaryhilbert
B
30

You can use maven itself to run it, I believe it sets the classpath for you.

mvn compile

will compile it then you run:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"  

which will execute it.

You can see http://www.vineetmanohar.com/2009/11/3-ways-to-run-java-main-from-maven/ for some more info on ways to run (including passing command-line args to the thing you want to run)

Boisleduc answered 16/5, 2011 at 22:33 Comment(0)
H
19

You can make a jar executable by adding the Main-Class attribute to its manifest file. In Maven this is done by the archiver plugin. To add the Main-Class attribute, add this to your pom.xml:

 <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>

You can now run your jar with the command: java -jar myjar.jar or by double clicking on it (not available in all platforms).

Hilaryhilbert answered 16/5, 2011 at 22:34 Comment(2)
To make this solution work I needed to add classpathMavenRepositoryLayout=true and classpathPrefix=/home/.../.m2/repository/ to the manifest section also because default behavior is to just put the name of the jar in the manifest (no reference to it's location in the filesystem).Isidroisinglass
Yes, the default behaviour expects the dependecies to be on the same directory of your main jar. Since you have the dependencies on your local repo, with your solution, the jar can be run from anywhere in your system.Hilaryhilbert
C
3

If you want it simple for you and others, then you can generate a jar with all dependencies in it, using the maven-assembly-plugin. Example is here: http://maven.apache.org/plugins/maven-assembly-plugin/usage.html, section Execution: Building an Assembly

Calabar answered 16/5, 2011 at 22:33 Comment(0)
B
3

You can use the maven-shade-plugin which will create an executable uber war with all dependencies.

OR

Use the appassembler-plugin which creates a script that imports all dependencies and lets you execute a main class from the command line.

Banky answered 16/5, 2011 at 22:55 Comment(3)
I didn't try the shade plugin, but appassembler works for me. Thanks!Isidroisinglass
The appassembler-plugin ling is dead as of 2020-01-22Postglacial
The new link is probably mojohaus.org/appassembler/appassembler-maven-pluginThiel
M
0

For completeness, it's worth mentioning another option.

Spring Boot can create an executable JAR file on UNIX systems.

Moskowitz answered 22/10, 2023 at 23:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.