web-dev-qa-db-ja.com

Mavenを使用して依存関係をjarに含める

1つのjarファイルにすべての依存関係を含めるようにmaven(2.0.9)に強制する方法はありますか?

私は単一のjarファイルにビルドするプロジェクトを持っています。依存関係のクラスもjarにコピーする必要があります。

更新:jarファイルをjarファイルに含めることができないことを知っています。依存関係として指定されているjarファイルを解凍し、クラスファイルを私のjarファイルにパッケージ化する方法を探しています。

307
racer

これを行うには、maven-Assemblyプラグインを「jar-with-dependencies」記述子と共に使用します。これは、これを行うpom.xmlの1つの関連チャンクです。

  <build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-Assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
431
John Stauffer

Maven 2では、これを行う正しい方法は、 事前定義された記述子ファイル を持つ Maven 2アセンブリプラグイン を使用することです。この目的とあなたがただコマンドラインで使うことができるということ:

mvn Assembly:assembly -DdescriptorId=jar-with-dependencies

このjarを実行可能にしたい場合は、実行するメインクラスをプラグイン設定に追加するだけです。

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-Assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

そのアセンブリを通常のビルドプロセスの一部として作成したい場合は、 single または directory-single をバインドする必要があります。 Assemblyの目標は、コマンドラインから)ライフサイクルフェーズ(packageが意味をなす)までの間にのみ実行されるべきです。

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-Assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>create-my-bundle</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

あなたのニーズに合うようにconfiguration要素を適応させてください(例えば、話されているマニフェストのもので)。

125
Pascal Thivent

実行可能なjarファイルを作成したい場合は、メインクラスも設定する必要があります。それで、完全な設定はそうあるべきです。

    <plugins>
            <plugin>
                 <artifactId>maven-Assembly-plugin</artifactId>
                 <executions>
                     <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>single</goal>
                          </goals>
                      </execution>
                  </executions>
                  <configuration>
                       <!-- ... -->
                       <archive>
                           <manifest>
                                 <mainClass>fully.qualified.MainClass</mainClass>
                           </manifest>
                       </archive>
                       <descriptorRefs>
                           <descriptorRef>jar-with-dependencies</descriptorRef>
                      </descriptorRefs>
                 </configuration>
         </plugin>
   </plugins>
28
abdiel

日陰のmavenプラグインがあります依存関係のパッケージ化と名前変更に使用できます(クラスパスの依存関係の問題を回避するため)。

17
Thomas Jung

<classifier>タグを使用して、新しく作成したjarを使用できます。

<dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>your.artifact.id</artifactId>
        <version>1.0</version>
        <type>jar</type>
        <classifier>jar-with-dependencies</classifier>
    </dependency>
</dependencies>
13
lasantha

あなたが(私のように)上で説明したjar-with-dependenciesアプローチを特に好まないのであれば、たとえそれがたとえそうであっても、単純にWARプロジェクトをビルドするのが私の好みです。作成しているスタンドアロンJavaアプリケーションのみ

  1. 通常のMaven jarプロジェクトを作成します。これにより、(依存関係なしで)jarファイルが構築されます。

  2. また、Maven war-projectを設定します(空のsrc/main/webapp/WEB-INF/web.xmlファイルのみを使用します)。これはあなたのjar-projectを依存関係として持つだけで、あなたのjar-projectをあなたのwar-projectの下の<module>にするものです。 (このwar-projectはすべてのjarファイルの依存関係をZipファイルにラップするための単純なトリックです。)

  3. Warファイルを作成するためにwarプロジェクトを構築します。

  4. 展開ステップでは、.warファイルの名前を* .Zipに変更して解凍します。

これで、jarファイルと、アプリケーションを実行するために必要なすべての依存関係を含むlibディレクトリ(必要な場所に移動できます)ができました。

Java -cp 'path/lib/*' MainClass

(クラスパスのワイルドカードはJava-6以上で動作します)

私はこれがmavenでセットアップするのがより簡単であり(Assemblyプラグインをいじる必要もない)そしてあなたにアプリケーション構造のより明瞭なビューを与える(プレーンビューで全ての依存jarのバージョン番号を見るでしょう)単一のjarファイルにすべてを詰まらせないようにしてください。

12
Rop

http://fiji.sc/Uber-JAR は選択肢の優れた説明を提供します。

Uber-JARを構築するための3つの一般的な方法があります。

  1. 網掛けなしすべてのJARファイルを解凍し、それらを1つのJARに再パックします。
    • Pro:Javaのデフォルトのクラスローダーで動作します。
    • 欠点:同じパスを持つ複数のJARファイル(META-INF/services/javax.script.ScriptEngineFactoryなど)に存在するファイルは互いに上書きされるため、誤った動作をします。
    • ツール:Mavenアセンブリプラグイン、Classworlds Uberjar
  2. 影付き。陰影のないものと同じですが、すべての依存関係のすべてのパッケージの名前を変更する(つまり、「陰影を付ける」)。
    • Pro:Javaのデフォルトのクラスローダーで動作します。一部(すべてではない)の依存関係バージョンの衝突を避けます。
    • 欠点:同じパスを持つ複数のJARファイル(META-INF/services/javax.script.ScriptEngineFactoryなど)に存在するファイルは互いに上書きされるため、誤った動作をします。
    • ツール:Maven Shade Plugin
  3. JARのJAR最後のJARファイルには、他のJARファイルが埋め込まれています。
    • Pro:依存バージョンの衝突を回避します。すべてのリソースファイルは保持されます。
    • 欠点:JavaがラップされたJARファイルからクラスをロードできるようにするために、特別な「ブートストラップ」クラスローダーをバンドルする必要があります。クラスローダーの問題のデバッグはより複雑になります。
    • ツール:Eclipse JAR File Exporter、One-JAR。
10
André Valenti

Eclipse Lunaとm2Eclipseに関する私の決定的な解決策:カスタムクラスローダー(ダウンロードしてプロジェクトに追加してください、5つのクラスのみ): http://git.Eclipse.org/c/jdt/Eclipse.jdt.ui .git/plain/org.Eclipse.jdt.ui/jar%20in%20jar%20loader/org/Eclipse/jdt/internal/jarinjarloader / ;このクラスローダーは1つのjarクラスローダーの中でも最高で、非常に高速です。

<project.mainClass>org.Eclipse.jdt.internal.jarinjarloader.JarRsrcLoader</project.mainClass> <project.realMainClass>my.Class</project.realMainClass>

JIJ定数「Rsrc-Class-Path」から「Class-Path」で編集
mvn clean依存性:コピー依存性パッケージ
はシンクラスローダを使用してlibフォルダに依存関係を持つjarファイルを作成します

<build>
    <resources>
        <resource>
            <directory>src/main/Java</directory>
            <includes>
                <include>**/*.Java</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*</include>
            </includes>
            <targetPath>META-INF/</targetPath>
        </resource>
        <resource>
            <directory>${project.build.directory}/dependency/</directory>
            <includes>
                <include>*.jar</include>
            </includes>
            <targetPath>lib/</targetPath>
        </resource>
    </resources>
<pluginManagement>
        <plugins>

            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${project.mainClass}</mainClass>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>

                        <manifestEntries>
                            <Rsrc-Main-Class>${project.realMainClass}  </Rsrc-Main-Class>
                            <Class-Path>./</Class-Path>
                        </manifestEntries>

                    </archive>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
4
        <!-- Method 1 -->
        <!-- Copy dependency libraries jar files to a separated LIB folder -->
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive> 
                <stripVersion>false</stripVersion>
            </configuration>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Add LIB folder to classPath -->
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>


        <!-- Method 2 -->
        <!-- Package all libraries classes into one runnable jar -->
        <plugin>
            <artifactId>maven-Assembly-plugin</artifactId>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
        </plugin>            
3
Leslie Li

Mavenを脇に置くと、JARライブラリをMain Jarの中に置くことができますが、独自のクラスローダを使用する必要があります。

このプロジェクトをチェックしてください:One-JAR リンクテキスト

1
medopal

この記事は少し古いかもしれませんが、私も最近同じ問題を抱えていました。 John Staufferによって提案された最初の解決策は良い解決策ですが、私はこの春作業しているときにいくつかの問題を抱えていました。私が使用しているSpringの依存関係jarファイルには、同じパスと名前を共有するプロパティファイルとxmlスキーマ宣言がいくつかあります。これらのjarファイルは同じバージョンのものですが、jar-with-dependenciesmaven-goalは最後に見つかったファイルでthesesファイルを上書きすることでした。

結局のところ、春の瓶が正しいプロパティファイルを見つけることができなかったので、アプリケーションは起動できませんでした。この場合、Ropによって提案された解決策は私の問題を解決しました。

それ以来、スプリングブートプロジェクトも存在します。パッケージの目標をオーバーロードし、独自のクラスローダを提供するMavenの目標を提供することによって、この問題を管理するための非常にクールな方法があります。 spring-bootsリファレンスガイド を参照してください。

0

おかげで私はPOM.xmlファイルのスニペットの下に追加してMp問題を解決し、すべての依存jarファイルを含むfat jarファイルを作成しました。

<plugin>
    <artifactId>maven-Assembly-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <descriptorRefs>
                <descriptorRef>dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
</plugins>
0
Rajeev Rathor

この答えを見てください。

Java JARファイルとして実行されるインストーラを作成しています。インストールディレクトリの適切な場所にWARファイルとJARファイルを解凍する必要があります。依存関係プラグインは、コピーの目的でパッケージフェーズで使用でき、Mavenリポジトリ内の任意のファイル(WARファイルを含む)をダウンロードして、必要な場所にそれらを書き込みます。出力ディレクトリを$ {project.build.directory}/classesに変更したところ、通常のJARタスクには自分のファイルが正しく含まれていました。それからそれらを抽出してインストールディレクトリに書き込むことができます。

<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
    <execution>
        <id>getWar</id>
        <phase>package</phase>
        <goals>
            <goal>copy</goal>
        </goals>
        <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>the.group.I.use</groupId>
                    <artifactId>MyServerServer</artifactId>
                    <version>${env.Java_SERVER_REL_VER}</version>
                    <type>war</type>
                    <destFileName>myWar.war</destFileName>
                </artifactItem>
            </artifactItems>
            <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
    </execution>
</executions>
0
millebi