2013-03-05 81 views
7

尝试修改现有的Java/Tomcat应用程序以在其上执行tutorial之后在Heroku上部署,并遇到AppAssembler未找到入门级的一些问题。运行目标/ bin/webapp(或部署到Heroku)结果为Error: Could not find or load main class org.stopbadware.dsp.MainMaven AppAssembler找不到类

执行java -cp target/classes:target/dependency/* org.stopbadware.dsp.Main但是正常运行。这里的pom.xml的相关部分:

<plugin> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>appassembler-maven-plugin</artifactId> 
     <version>1.1.1</version> 
     <configuration> 
      <assembleDirectory>target</assembleDirectory> 
      <programs> 
       <program> 
        <mainClass>org.stopbadware.dsp.Main</mainClass> 
        <name>webapp</name> 
       </program> 
      </programs> 
     </configuration> 
     <executions> 
      <execution> 
       <phase>package</phase> 
       <goals> 
        <goal>assemble</goal> 
       </goals> 
      </execution> 
     </executions> 
    </plugin> 

我的猜测是mvn package导致AppAssembler不使用正确的类路径,有什么建议?

+0

你能展示生成的脚本(.sh/.bat)是怎么样的? – khmarbaise 2013-03-05 19:28:50

+0

生成的脚本可以在http://pastebin.com/f9gbVMgx看到 - 找不到的主类在PROJECTROOT/src/org/stopbadware/dsp/ – Exupery 2013-03-05 19:42:11

回答

5

你的神器的包装必须设置为jar,否则主类是找不到的。

<pom> 
    ... 
    <packaging>jar</packaging> 
    ... 
</pom> 

的神器本身在类路径的末尾增加,因此,不外乎一个JAR文件会产生什么影响。

1

首先,您正在使用旧版本的appassembler-maven-plugin,当前版本为1.3。

什么,我不明白你为什么要定义

<assembleDirectory>target</assembleDirectory> 

文件夹。对此有一个很好的默认值。所以通常你不需要它。除此之外,您不需要定义与包阶段相关的显式执行,导致appassembler-maven-plugin is by default bound to the package phase

此外,您可以使用useWildcardClassPath配置选项来缩短您的类路径。

<configuration> 
    <useWildcardClassPath>true</useWildcardClassPath> 
    <repositoryLayout>flat</repositoryLayout> 
    ... 
    </configruation> 

而且该生成的脚本中调用显示误差取决于东西,所有的依赖关系所在的文件夹在资源库中的位置比定义生成的脚本不同。

+0

这是我第一次使用AppAssembler,所以我使用的是Heroku在前面提到的教程中。使用1。3,删除目录和执行引用,并添加通配符选项没有效果,仍然得到相同的错误。显然,在构建脚本时,它不会创建正确的类路径,可悲的是AppAssembler文档非常有限,并且看起来并不表示如何显式添加到生成的类路径。 – Exupery 2013-03-06 13:54:45

+0

最好的做法是在[jira](https://jira.codehaus.org/browse/MAPPASM)上放置一个示例项目(使用它的pom.xml)并创建一个问题,或者只是私下发送pom.xml文件给我我可以看看你的问题。 – khmarbaise 2013-03-09 18:27:09

+0

您可以在http://pastebin.com/11WmjBmB上看到pom.xml - appassembler生成的脚本位于http://pastebin.com/f9gbVMgx,并且在类路径中丢失的PROJECTROOT/target/classes条目为通过添加'“$ BASEDIR”/ classes'来修复。 – Exupery 2013-03-11 15:34:34

1

能够通过将"$BASEDIR"/classes添加到生成的脚本中的CLASSPATH行来解决此问题。由于脚本在每次调用mvn package时被重写,我写了一个简短脚本,调用mvn package,然后添加所需的类路径条目。

显然有点破解,但经过8个多小时的尝试一个更“适当”的解决方案,这将不得不现在做。肯定会有更多优雅的方法来纠正这里提出的类路径。

3

尝试:

mvn clean package jar:jar appassembler:assemble 
+2

在我的本地机器上工作正常,但没有部署到Heroku。从我所看到的没有办法将Heroku的maven命令从默认的'mvn clean install'(将jar:jar appassembler:assemble'添加到MAVEN_OPTS中没有任何作用)。 – Exupery 2013-11-03 16:20:43

1

可以设置CLASSPATH_PREFIX环境变量:

export CLASSPATH_PREFIX=target/classes 

将得到预先计划在生成的脚本的类路径。

1

我前段时间阅读过该教程,并且遇到了非常类似的问题。我带来了一些不同的方法,这对我来说非常合适。

首先,因为它是前面提到的,你必须保持你的POM的类型jar<packaging>jar</packaging>) - 这要归功于,appassembler插件会产生从你的类的JAR文件,并将其添加到类路径。所以谢谢你的错误将消失。

请注意,本教程的Tomcat是从应用程序源目录实例化的。在很多情况下,这已经足够了,但是请注意,使用这种方法,您将无法使用Servlet @WebServlet注释作为/WEB-INF/classes,而源代码为空,Tomcat将无法扫描您的servlet类。因此,HelloServlet该教程中的servlet将不起作用,除非您按照here所述添加了一些额外的Tomcat初始化(资源配置)(顺便说一下,您会发现更多讨论该资源配置的SO问题)。期间生成的目录作为应用程序的我的源目录package和使用

我运行一个org.apache.maven.plugins:maven-war-plugin插件(exploded目标):

我做了一些不同的方法。用这种方法我的web应用程序目录将有/WEB-INF/classes“填充”类。这反过来将允许Tomcat正确执行扫描作业(即,Servlet @WebServlet注释将起作用)。

我也不得不改变我的应用程序在启动类来源:

public static void main(String[] args) throws Exception { 
    // Web application is generated in directory name as specified in build/finalName 
    // in maven pom.xml 
    String webappDirLocation = "target/embeddedTomcatSample/"; 
    Tomcat tomcat = new Tomcat(); 

    // ... remaining code does not change 

更改POM,我说 - 包括maven-war-plugin之前appassembler插件:

... 
<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-war-plugin</artifactId> 
    <version>2.5</version> 
    <executions> 
     <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>exploded</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
... 

请注意,被称为exploded的目标。

我希望小小的改动能帮助你。在该教程和Maven构建


还有一个注释:请注意,本教程是写给显示是多么简单构建一个应用程序,并在Heroku上运行它。但是,这不是Maven构建的最佳方法。

Maven的建议是,你应该坚持每个POM生成一个工件。你的情况有应两个产物:

  • 的Tomcat启动
  • Tomcat Web应用程序

双方应建立作为单独的POM和从父POM模块引用。如果你看一下这个教程的复杂性,把它分成两个模块没什么意义。但是如果你的应用程序变得越来越复杂(并且启动器会获得一些额外的配置等),那么做出这种“分割”将会很有意义。事实上,已经创建了一些“Tomcat启动器”库,所以你可以使用其中一个。