Reputation: 53119
It actually took me a long while to notice. When I run the project in netbeans, it works just as expected. But when I do the Build
I get PROJECTNAME-1.0-SNAPSHOT.jar
file that doesn't do anything. When unpacked, it looks like this:
This is suspicious, before Maven, my compiled file looked like this:
Shouldn't the Main
class be in the jar file root? How does JVM know which main class to run?
There's something disturbing about the MANIFEST.MF too:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.1
Created-By: 1.7.0_45-b18 (Oracle Corporation)
Class-Path: lib/alloy.jar lib/jna-platform.jar lib/jna.jar
X-COMMENT: Main-Class will be added automatically by build
Main-Class: Main
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Jakub
Build-Jdk: 1.8.0_31
Seems like Main-Class
entry is missing...
Upvotes: 0
Views: 1228
Reputation: 65793
Sadly many IDE's provide a simple mechanism for packaging all of your library jars into your main build jar. This is both frowned-upon and potentially hazardous to your deployable - you should really deploy all of the used libraries separately and use your class-path to join them all up.
As Maven attempts to make doing it right the easiest way it is designed to by default build your jar to contain just your code and no more. If you can stick with this solution then it may be worth your while doing so.
However, sometimes it is necessary to make this happen, perhaps to duplicate existing build results while switching to Maven or maybe deployment is enough of a nightmare without having to deploy dozens of libraraies too. To achieve this you can build what the Maven community call an Uber-Jar using the Maven Shade plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<!-- Make sure jaxb is included. -->
<artifact>com.sun.xml.bind:jaxb-impl</artifact>
<includes>
<include>*.*</include>
</includes>
</filter>
<filter>
<!-- Make sure jtds is included. -->
<artifact>net.sourceforge.jtds:jtds</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.sf</exclude>
<exclude>META-INF/*.dsa</exclude>
<exclude>META-INF/*.rsa</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
Note that building uber-jars is generally not the best approach - there are many discussions about this online. Also there are many relational problems with the maven-shade-plugin
itself as it interferes with Maven's mechanism for determining dependencies.
That said - if you must do it then the shade plugin is your guy.
NB: Just because this excludes licences does not mean this is a good idea - this is there to avoid duplicate file name issues in the uber jar.
See this interesting blog by MKYong about the pros and cons of using assembly/shade/one-jar
.
Upvotes: 1
Reputation: 4462
Use maven-jar-plugin for make your jar
executable. For me actual code below:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>my.main.class</mainClass>
</manifest>
</archive>
<outputDirectory>${project.build.directory}/result</outputDirectory>
</configuration>
</plugin>
Alse usefull exec-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<mainClass>my.main.class</mainClass>
<!--
<commandlineArgs>-d 5409 -c 467 -t 2 -dlg true</commandlineArgs>
-->
</configuration>
</plugin>
Upvotes: 1