1

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.

4

1 回答 1

3

我看到的两件事是

  1. classpath设置不正确。

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

    这里的 SCRIPTLOC 不是根目录。这是<the_complete_path_from_root>/bin

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

    这最终评估为<the_complete_path_from_root>/bin/lib

    您稍后lib会将文件夹添加到其中,该文件夹实际上并不包含您的 jar。因此,要添加到类路径的正确路径是lib jar 所在的文件夹,然后它将能够找到com.foo.bar.MainClass.

  2. 要将 Main 类添加到清单文件中,您需要将以下内容添加到pom.xml文件中。

    <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>
    
于 2013-02-14T17:33:41.160 回答