Mavenでjarに依存関係を含める


353

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

1つのjarファイルにビルドするプロジェクトがあります。依存関係のクラスもjarにコピーする必要があります。

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




2
jarファイルをmavenのjarファイルに含める方法は?
Kush Patel

回答:


488

これを行うには、「jar-with-dependencies」記述子を持つmaven-assemblyプラグインを使用します。これは、これを行う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>

30
attached目標は推奨されません。singleまたはdirectory-single目標の代わりに優先されなければなりません。
Pascal Thivent 2009年

16
directory-singleも非推奨になりました。
James McMahon

14
公式サイトでシングルを使用することをお勧めします
mateuszb 2013年

42
新しいmvnの人が私のように動けなくなった場合は、<project>内の<build>内の<plugins>にプラグインを追加します。
DA

10
@ Christian.tucker ./target/example-0.0.1-SNAPSHOT.jar./target/example-0.0.1-SNAPSHOT-jar-with-dependencies.jar
テクノクラート2015年

145

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

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>

通常のビルドプロセスの一部としてそのアセンブリを作成する場合は、次のように、単一またはディレクトリ単一の目標(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要素をニーズに合わせて調整します(たとえば、マニフェストを読み上げるなど)。


私はこれを正確に試していますが、ビルドがスムーズに実行されても、プラグインが実行されず、jarファイルが作成されません。私が行き詰まっている可能性のある一般的な落とし穴はありますか?
posdef 2012年

6
それは私のために働いていますが、探求しています。ビルド後、2つのjarが作成されます。1つはプロジェクトのArtifactid-version、もう1つはArtifactid-version- "jar-with-dependencies"です。しかし、私は1つのjarファイルのみをビルドしてほしい。他に方法はありますか
Souvik Bhattacharya

38

実行可能な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>

2
jarの名前が「jar-with-dependencies」によって追加されるのはなぜですか?回避策はありますか?
Tina J

1
@Tina J タグ<appendAssemblyId>false</appendAssemblyId>内に追加<configuration>して、最終的な名前の「-jar-with-dependencies」サフィックスを除外できます。
ccu

19

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


2
ファイル名の一部としてjar-with-dependenciesを使用したくない場合。
カイル


これは私にとって最良の答えだった... :)
アナンドVarkeyフィリップス

17

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

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

14

上記のjar-with-dependenciesアプローチが特に好きではない場合、私が好むmaven-solutionは、ビルドしているスタンドアロンのJavaアプリケーションのみであっても、WARプロジェクトを単にビルドすることです。

  1. (依存関係なしで)jarファイルを構築する通常のmaven jarプロジェクトを作成します。

  2. また、jarプロジェクトが次のようになっているmaven warプロジェクト(空のsrc / main / webapp / WEB-INF / web.xmlファイルのみを使用してmaven-buildの警告/エラーを回避)をセットアップします。依存関係を作成し、jarプロジェクトを<module>war プロジェクトの下に配置します。(このwarプロジェクトは、すべてのjarファイルの依存関係をzipファイルにラップする単純なトリックにすぎません。)

  3. warプロジェクトをビルドしてwarファイルを作成します。

  4. 展開手順では、.war-fileの名前を* .zipに変更して解凍します。

これで、jarおよびアプリケーションを実行するために必要なすべての依存関係を含むlib-directory(必要な場所に移動できます)ができました。

java -cp 'path/lib/*' MainClass

(クラスパスのワイルドカードはJava-6以降で機能します)

これはmavenでのセットアップが簡単で(アセンブリプラグインをいじる必要がない)、アプリケーション構造のより明確なビューを提供します(プレーンビューですべての依存jarのバージョン番号が表示されます)。すべてが単一のjarファイルに詰まるのを避けます)。


Eclipseの「Runnable jarとしてエクスポート」と同じですか?これにより、「JARを使用してすべての依存関係をパッケージ化」することを選択できるため、jarとともに、project-libフォルダー内のすべての依存関係を取得します。
WesternGun、2018

@FaithReaper-それは「同じ」かもしれない、私はそれを試したことがない。しかし、Eclipseを使用する場合、簡単にスクリプト化することはできないと思います。これは、自動化されたビルド+デプロイパイプラインを実装する場合の要件です。たとえば、Jenkins-serverにgit source-repositoryなどからのビルドを実行させます。
2018

12

http://fiji.sc/Uber-JARは、代替の優れた説明を提供します。

uber-JARを構築するには、3つの一般的な方法があります。

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

1
サービスに関してはあまり当てはまりません。シェードプラグインにはトランスフォーマーがあり、そのうちの1つはMETA-INF/servicesディレクトリ下のファイルのコンテンツを連結するためのものです。詳細はこちら:maven.apache.org/plugins/maven-shade-plugin/examples/…–
インビトロ

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

4

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>

JIJConstants "Rsrc-Class-Path"から "Class-Path"への編集
mvn clean dependency:copy-dependenciesパッケージ
は、薄いクラスローダーを使用して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>

maven-dependency-plugin <outputDirectory>が機能せず、常に「dependency」フォルダーに書き込みます
Glaucio Southier

プロジェクトの依存関係を含む内部フォルダー "dependency"を持つjarを作成し、それをMANIFEST.MFに配置します
Glaucio Southier '10

<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>
Glaucio Southier、2015年

1
この回答に基づいて、私はこのプロジェクトを作成しました。pomファイル以外は何も変更する必要はありません:github.com/raisercostin/jarinjarloader
raisercostin


0

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

最終的に、Spring jarが正しいプロパティファイルを見つけられなかったため、アプリケーションを起動できませんでした。この場合、Ropによって提案されたソリューションは私の問題を解決しました。

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


0

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

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

POM.xmlファイルのスニペットの下に追加したおかげで、Mpの問題が解決し、すべての依存jarを含むファット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>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.