简体   繁体   中英

Maven: Build runnable jar and then add to zip with maven-assembly-plugin

I have a maven problem that should be easy to solve, but is proving to be a bit difficult.

I have a project that builds a jar, and needs that jar to be able to execute a class com.foo.bar.MainClass , but I need to be able to deploy it along with a few scripts and its dependencies like

some-product-1.0.0.zip
  bin/
    some-product.sh
  lib/
    some-product-1.0.0.jar
    dependency1.jar
    dependency2.jar

I can get it to make this structure quite easily. My pom.xml looks like

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>com.foo.bar.MainClass</mainClass>
                <addClasspath>true</addClasspath>
            </manifest>
        </archive>
        <descriptors>
            <descriptor>assembly.xml</descriptor>
        </descriptors>
    </configuration>
</plugin>

and my assembly.xml is

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>bin</id>
    <formats>
        <format>zip</format>
    </formats>
    <files>
        <file>
            <source>src/main/scripts/some-product.sh</source>
            <outputDirectory>/bin</outputDirectory>
        </file>
    </files>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/lib</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <scope>compile</scope>
        </dependencySet>
    </dependencySets>
</assembly>

And some-product.sh looks like

SCRIPTLOC=$( readlink -f $( dirname "${BASH_SOURCE[0]}" ) )
LIBS="$( dirname $SCRIPTLOC )/lib"
# builds a : joined list of all the jars in the lib directory
MYCLASSES=$(echo $LIBS/*.jar | tr ' ' ':')

java -cp "$CLASSPATH:$MYCLASSES" com.foo.bar.MainClass

but what I got when I ran the script was

Exception in thread "main" java.lang.NoClassDefFoundError: com/foo/bar/MainClass
Cause by: java.lang.ClassNotFoundException com.foo.bar.MainClass
    at ...
Could not find the main class: com.foo.bar.MainClass.  Program will exit.

When I examined the jar that contains the class, the manifest only had

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: <myname>
Build-Jdk: 1.6.0_27

telling me that it did not add the main class to the manifest.

I've googled this problem for quite some time without luck, and the examples on the assembly plugin's website are terrible. How can I get maven to build this jar correctly and add it to the zip?

EDIT : I did need the maven-jar-plugin in my pom, but my real problem was that I was using Cygwin and the classpath separator it expected was ; not : . My solution was to write some code to figure out which classpath separator to use, and with the jar plugin it works perfectly now.

Two things I see are

  1. The classpath is not set properly.

      SCRIPTLOC=$( readlink -f $( dirname "${BASH_SOURCE[0]}" ) ) 

    Here the SCRIPTLOC is not the root dir. It is <the_complete_path_from_root>/bin

      LIBS="$( dirname $SCRIPTLOC )/lib" 

    This finally evaluates to <the_complete_path_from_root>/bin/lib

    And you are later adding the lib folder to it, which does not actually contain your jar. So, the correct path to be added to the classpath is lib folder where the jar is present, then it would be able to find the com.foo.bar.MainClass .

  2. For adding the Main class to the manifest file, you'll need to add the following to pom.xml file.

     <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.someclass.Main</mainClass> <packageName>com.someclass</packageName> </manifest> <manifestEntries> <mode>development</mode> <url>${pom.url}</url> </manifestEntries> </archive> </configuration> </plugin> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM