2013-03-05 103 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啓動器」庫,所以你可以使用其中一個。