2012-08-01 43 views
77

我使用Maven的在我的獨立應用程序,我要打包所有的依賴庫中的文件夾在我的JAR文件,如這裏的一個答案中提到:如何使用Maven將所有必需的JAR文件放入最終JAR文件內的庫文件夾中?

How can I create an executable JAR with dependencies using Maven?

我想我最後的JAR文件都包含依賴關係的JAR文件庫文件夾,不喜歡什麼使依賴於像在文件夾中的.m2 Maven的層級文件夾的形式maven-shade-plugin

嗯,其實當前的配置我想要做什麼,但我有運行應用程序時加載的JAR文件的問題。我無法加載這些類。

這裏是我的配置:

<plugins> 

    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-dependency-plugin</artifactId> 
     <executions> 
      <execution> 
       <id>copy-dependencies</id> 
       <phase>prepare-package</phase> 
       <goals> 
        <goal>copy-dependencies</goal> 
       </goals> 
       <configuration> 
        <outputDirectory>${project.build.directory}/classes/lib</outputDirectory> 
        <overWriteReleases>false</overWriteReleases> 
        <overWriteSnapshots>false</overWriteSnapshots> 
        <overWriteIfNewer>true</overWriteIfNewer> 
       </configuration> 
      </execution> 
     </executions> 
    </plugin> 

    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-jar-plugin</artifactId> 
     <configuration> 
      <archive> 
       <manifest> 
        <addClasspath>true</addClasspath> 
        <classpathPrefix>lib/</classpathPrefix> 
        <mainClass>com.myapp.MainClass</mainClass> 
       </manifest> 
      </archive> 
     </configuration> 
    </plugin> 

    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <configuration> 
      <source>1.6</source> 
      <target>1.6</target> 
     </configuration> 
    </plugin> 

    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-dependency-plugin</artifactId> 
     <executions> 
      <execution> 
       <id>install</id> 
       <phase>install</phase> 
       <goals> 
        <goal>sources</goal> 
       </goals> 
      </execution> 
     </executions> 
    </plugin> 

    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-resources-plugin</artifactId> 
     <version>2.5</version> 
     <configuration> 
      <encoding>UTF-8</encoding> 
     </configuration> 
    </plugin> 

</plugins> 

該項目從Eclipse的罰款,並在JAR文件放入庫中的文件夾我最後的JAR文件中,因爲我想,但運行從最終的JAR文件時目標文件夾我總是得到ClassNotFoundException

Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext 
Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
Could not find the main class: com.myapp.MainClass. Program will exit. 

我怎樣才能解決這個例外?

+1

你使用哪個命令來運行jar?大概你可能更喜歡maven exec插件? – 2012-08-01 12:05:42

+0

與POM文件相比,異常消息是否過期?看起來正在搜索主類「com.myapp.MainClass」,而不是「com.tastycafe.MainClass」。 – 2012-08-01 12:06:04

+0

@Duncan Jones,複製粘貼問題,我編輯了問題 – 2012-08-01 12:28:28

回答

0

這顯然是一個classpath的問題。考慮到在IDE外部運行程序時,類路徑必須稍作更改。這是因爲IDE將加載其他JAR相對於項目的根文件夾,而在最終JAR的情況下,這通常是不正確的。

我喜歡在這種情況下做的是手工打造的JAR。我最多需要5分鐘的時間才能解決問題。我不建議你這樣做。找到一種使用Maven的方式,這是它的目的。

+0

手動構建jar是什麼意思? – 2012-08-01 11:58:33

+0

@SoboLAN手動構建JAR不是一個解決方案。目的是使用Maven,這與「手動」完全相反! – 2012-08-01 11:59:34

+0

@DuncanJones你是完全正確的。我建議他使用Maven來做到這一點。但是,我沒有經驗,也不知道推薦的解決方案。我編輯了我的答案以反映這一點。 – 2012-08-01 12:01:02

21

最簡單和最有效的方式是使用超級插件這樣的:

  <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-shade-plugin</artifactId> 
      <executions> 
       <execution> 
        <phase>package</phase> 
        <goals> 
         <goal>shade</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <finalName>uber-${artifactId}-${version}</finalName> 
      </configuration> 
     </plugin> 

,你將有非歸在同一個JAR文件。

+0

除了我目前的配置使用它?這個插件做了什麼? – 2012-08-01 11:59:48

+13

我不想讓我的jar文件看起來像這樣,我想要像netbean那樣在jar文件內的lib文件夾中擁有所有依賴項。 – 2012-08-01 12:02:13

3

Here's我如何做到這一點:

<plugin> 
      <artifactId>maven-assembly-plugin</artifactId> 
      <version>2.2</version> 
      <configuration> 
       <appendAssemblyId>false</appendAssemblyId> 
       <descriptorRefs> 
        <descriptorRef>jar-with-dependencies</descriptorRef> 
       </descriptorRefs> 
       <archive> 
        <manifest> 
         <mainClass>com.project.MainClass</mainClass> 
        </manifest> 
       </archive> 
      </configuration> 
     </plugin> 

然後我就跑:

mvn assembly:assembly 
+1

這不是我想要的,請仔細閱讀問題。 – 2012-08-01 12:56:05

+1

請注意,您應該總是事先做一個編譯,因爲'assembly'只會將任何內容放在JAR中的「target/classes」中。這將確保JAR包含您最近對源代碼所做的任何更改。所以,你應該這樣做:'mvn clean compile assembly:assembly'。 – naXa 2014-09-17 10:30:00

21

更新:以下鏈接

<build> 
    <plugins> 
    <plugin> 
    <artifactId>maven-dependency-plugin</artifactId> 
    <executions> 
     <execution> 
     <phase>install</phase> 
      <goals> 
      <goal>copy-dependencies</goal> 
      </goals> 
      <configuration> 
      <outputDirectory>${project.build.directory}/lib</outputDirectory> 
      </configuration> 
     </execution> 
     </executions> 
    </plugin> 
    </plugins> 
</build> 
+1

這不是我想要的,請仔細閱讀問題 – 2012-08-01 13:08:43

+2

這將lib文件夾放在jar外面(這不是我想要的)。比把這個lib放在jar裏面好嗎?以及在這種情況下如何將應用程序交付給客戶? – 2012-08-01 13:30:03

+0

現在對我來說更清楚了。讓我做一個谷歌搜索。但我想知道爲什麼你想要複製所有依賴jar文件在指定的文件夾內的可執行jar文件。如果所有依賴jar文件都在jar文件中,爲什麼你需要將它們放在lib文件夾中? – 2012-08-01 13:35:15

57

以下是我的解決方案。測試它是否適合你:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-dependency-plugin</artifactId> 
    <executions> 
     <execution> 
      <id>copy-dependencies</id> 
      <phase>prepare-package</phase> 
      <goals> 
       <goal>copy-dependencies</goal> 
      </goals> 
      <configuration> 
       <outputDirectory>${project.build.directory}/classes/lib</outputDirectory> 
       <overWriteReleases>false</overWriteReleases> 
       <overWriteSnapshots>false</overWriteSnapshots> 
       <overWriteIfNewer>true</overWriteIfNewer> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-jar-plugin</artifactId> 
    <configuration> 
     <archive> 
      <manifest> 
       <addClasspath>true</addClasspath> 
       <!-- <classpathPrefix>lib</classpathPrefix> --> 
       <!-- <mainClass>test.org.Cliente</mainClass> --> 
      </manifest> 
      <manifestEntries> 
       <Class-Path>lib/</Class-Path> 
      </manifestEntries> 
     </archive> 
    </configuration> 
</plugin> 

的第一個插件放入目標/班/ lib文件夾中所有的依賴,而第二個包含在最終的JAR文件的庫文件夾,並配置Manifest.mf文件。

但是,您將需要添加自定義類加載代碼來加載JAR文件。

或者避免自定義類加載,你可以用「$ {} project.build.directory/lib下,但在這種情況下,你沒有最終的JAR文件,該文件違背了目的裏面的依賴關係。

它已經兩年有人問的嵌套JAR文件中的問題,但仍然存在我希望它能幫助別人

+1

用法:mvn install,cd target,java -jar MyJarFile-1.0.jar – djb 2015-04-09 22:52:00

+0

很酷,這也適用於cloudfoundry – Keymon 2015-09-08 16:54:13

+0

我錯過了什麼?這將創建一個清單類路徑條目,其中包含「lib /」和lib文件夾中的所有單個jar。這是打算?爲什麼? – gapvision 2016-02-25 17:50:38

1

我發現這個問題的答案:

http://padcom13.blogspot.co.uk/2011/10/creating-standalone-applications-with.html

不僅你會得到嗎?他將lib文件依賴於一個lib文件夾,你還可以得到一個bin目錄,同時擁有一個unix和一個dos可執行文件。

可執行程序最終會使用一個-cp參數調用java,該參數也列出了所有依賴庫。

整個批次位於目標文件夾內的一個裝配文件夾中。史詩。

============= 是的,我知道這是一箇舊的線程,但它仍然在搜索結果中很高,所以我認爲它可能有助於像我這樣的人。

9

executable packer maven plugin可用於此目的:創建包含所有依賴項的獨立Java應用程序作爲特定文件夾中的JAR文件。運行mvn package

<plugin> 
    <groupId>de.ntcomputer</groupId> 
    <artifactId>executable-packer-maven-plugin</artifactId> 
    <version>1.0.1</version> 
    <configuration> 
     <mainClass>com.example.MyMainClass</mainClass> 
    </configuration> 
    <executions> 
     <execution> 
      <goals> 
       <goal>pack-executable-jar</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 

內置JAR文件位於target/<YourProjectAndVersion>-pkg.jar

只需添加<build><plugins>段內的下列您pom.xml(一定要更換相應的mainClass值)。它的所有編譯時和運行時依賴項都將包含在JAR文件中的lib/文件夾中。

聲明:我是該插件的作者。

+0

將很好更改目標罐的名稱 – 2017-06-22 02:42:11

+0

我試過了,我可以說它的工作......正如你所說,這個插件創建一個jar文件,其庫(jar)到jar中的lib目錄.. 。配置真的很容易.. **我認爲這是這個問題的作者所期待的** ...我會給你我的投票... 唯一的缺點,我發現它(那'這是我爲什麼不能使用它的原因),當我執行我的jar並顯示應用程序(大約20秒)時可能會因爲在自定義類加載器中註冊庫的過程而延遲......但它是一個偉大的方法和一個優秀的插件... – 2017-08-06 02:21:53

相關問題