Wednesday, March 25, 2015

Creating Runnable JAR using Maven.

At times we need to create a runnable jar using maven. So that we can run it as following.

java -jar MyJar.jar

This can be achieved using 2 different ways as far as I have learnt.

  1. Using "maven-shade-plugin" Plugin of Maven
  2. Using "maven-jar-plugin" Plugin of Maven

Using "maven-shade-plugin" Plugin of Maven

This might be the easiest way of creating a jar file of your java program. Simply add the following plugin to pom.xml.

<project>
  ...
  <build>
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.3</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.hemika.samples.MyMainClass</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

Here we have to add the reference path of the class which contains the main method to the "mainClass" element in the xml.

Sometimes we might encounter the following exception.

Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

The reason for this is as follows...

" The reason java.lang.SecurityException is raised is because some dependency jar files are signed jar files. A jar file is signed by using jarsigner, which creates 2 additional files and places them in META-INF: a signature file, with a .SF extension, and a signature block file, with a .DSA, .RSA, or .EC extension. Since the uber-jar file is created, the signatures and integrity of signed JAR files are no longer valid. When the uber-jar file is executed, java.lang.SecurityException is thrown. " - maven shade plugin: Invalid signature file digest for Manifest main attributes

The solution is it add the following filter.

<configuration>
 <filters>
            <filter>
              <artifact>*:*</artifact>
              <excludes>
                <exclude>META-INF/*.SF</exclude>
                <exclude>META-INF/*.DSA</exclude>
                <exclude>META-INF/*.RSA</exclude>
              </excludes>
            </filter>
 </filters>
</configuration>

To build the jar, run the following command...

mvn clean install

...and thats all for making a shaded jar.

Click here to see a sample.

Using "maven-jar-plugin" Plugin of Maven

Using this way requires to use 2 maven plugins. After executing "mvn clean install", the target folder will contain the jar file and also a "lib" folder. The "lib" folder will contain all the dependencies. This way is more advantageous as the depending library files are available from outside of the jar. Later if we need to replace the dependency jar with a new version or so, this will become useful.

Add the following to the pom.xml.

<project>
  ...
  <build>
    <plugins>
      ...
      <plugin>
 <artifactId>maven-dependency-plugin</artifactId>
 <executions>
   <execution>
     <phase>install</phase>
     <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
       <outputDirectory>${project.build.directory}/lib</outputDirectory>
     </configuration>
   </execution>
 </executions>
      </plugin>
      <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-jar-plugin</artifactId>
 <configuration>
   <archive>
            <manifest>
       <addClasspath>true</addClasspath>
       <useUniqueVersions>false</useUniqueVersions>
       <classpathPrefix>lib/</classpathPrefix>
       <mainClass>com.hemika.samples.Main</mainClass>
            </manifest>
          </archive>
 </configuration>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

The class that has the main method needs to be added at the "mainClass" node in the xml.

To build the jar, run the following command...

mvn clean install

...and thats all for creating a runnable jar.

Click here to see a sample.

References...

No comments:

Post a Comment