2013-02-14 104 views
1

我有一个应该很容易解决的maven问题,但是证明有点困难。Maven:构建可运行jar,然后使用maven-assembly-plugin添加到zip文件

我有建立一个罐子,需要一个罐子能够执行一类com.foo.bar.MainClass项目,但我需要能够像

some-product-1.0.0.zip 
    bin/ 
    some-product.sh 
    lib/ 
    some-product-1.0.0.jar 
    dependency1.jar 
    dependency2.jar 
有一些脚本和它的依赖一起部署

我可以很容易地制作这个结构。我pom.xml看起来像

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

和我assembly.xml

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

而且some-product.sh看起来像

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 

,但我得到了什么,当我跑了剧本

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. 

当我检查了包含类的jar,清单只有

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

告诉我,它没有主类添加到清单。

我已经搜索了这个问题很长一段时间没有运气,程序集插件的网站上的例子是可怕的。我怎样才能得到maven正确建立这个罐子把它添加到zip?

编辑:我确实需要行家-JAR-插件在我的POM,但我真正的问题是,我用Cygwin和类路径分隔符,预计是;:。我的解决方案是编写一些代码来确定要使用哪个类路径分隔符,并且使用jar插件它现在可以很好地工作。

+0

为什么不使您的生活更轻松,使用[appassembler - Maven的插件(http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/),其中处理所有的东西已经。它为windows/unix生成一个脚本,并且会为你处理所有的类路径。 – khmarbaise 2013-02-18 18:03:10

回答

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文件夹它,这实际上并不包含你的罐子。所以,要添加到类路径中的正确路径是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> 
    
+0

1.类路径肯定是正确的设置,我以前已经在回声声明,以确保。 'dirname'命令会得到父目录([见文档](http://linux.die.net/man/1/dirname)) 2.我试过了,但是我得到了同样的错误,NoClassDefFoundException – bheklilr 2013-02-14 17:48:09

+1

好吧,所以它是你需要添加的'maven-jar-plugin'代码片段,用于将主类包含在清单文件中。 – mtk 2013-02-14 17:50:54

+0

对不起,我在完成它之前意外地提交了我的评论(总是忘记他们不是多行并按回车键)。我试过这个片段,但它仍然给我同样的错误=/ – bheklilr 2013-02-14 17:55:22

相关问题