maven(2.0.9)にすべての依存関係を単一のjarファイルに含めるように強制する方法はありますか?
1つのjarファイルにビルドするプロジェクトがあります。依存関係のクラスもjarにコピーする必要があります。
更新: jarファイルにjarファイルを含めるだけではできないことがわかっています。依存関係として指定されているjarを解凍し、クラスファイルを自分のjarにパッケージ化する方法を探しています。
maven(2.0.9)にすべての依存関係を単一のjarファイルに含めるように強制する方法はありますか?
1つのjarファイルにビルドするプロジェクトがあります。依存関係のクラスもjarにコピーする必要があります。
更新: jarファイルにjarファイルを含めるだけではできないことがわかっています。依存関係として指定されているjarを解凍し、クラスファイルを自分のjarにパッケージ化する方法を探しています。
回答:
これを行うには、「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>
attached
目標は推奨されません。single
またはdirectory-single
目標の代わりに優先されなければなりません。
directory-single
も非推奨になりました。
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ファイルを作成する場合は、メインクラスも設定する必要があります。したがって、完全な構成にする必要があります。
<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>
<appendAssemblyId>false</appendAssemblyId>
内に追加<configuration>
して、最終的な名前の「-jar-with-dependencies」サフィックスを除外できます。
シェードmavenプラグインがあります。依存関係のパッケージ化と名前変更に使用できます(クラスパスの依存関係の問題を回避するため)。
上記のjar-with-dependenciesアプローチが特に好きではない場合、私が好むmaven-solutionは、ビルドしているスタンドアロンのJavaアプリケーションのみであっても、WARプロジェクトを単にビルドすることです。
(依存関係なしで)jarファイルを構築する通常のmaven jarプロジェクトを作成します。
また、jarプロジェクトが次のようになっているmaven warプロジェクト(空のsrc / main / webapp / WEB-INF / web.xmlファイルのみを使用してmaven-buildの警告/エラーを回避)をセットアップします。依存関係を作成し、jarプロジェクトを<module>
war プロジェクトの下に配置します。(このwarプロジェクトは、すべてのjarファイルの依存関係をzipファイルにラップする単純なトリックにすぎません。)
warプロジェクトをビルドしてwarファイルを作成します。
展開手順では、.war-fileの名前を* .zipに変更して解凍します。
これで、jarおよびアプリケーションを実行するために必要なすべての依存関係を含むlib-directory(必要な場所に移動できます)ができました。
java -cp 'path/lib/*' MainClass
(クラスパスのワイルドカードはJava-6以降で機能します)
これはmavenでのセットアップが簡単で(アセンブリプラグインをいじる必要がない)、アプリケーション構造のより明確なビューを提供します(プレーンビューですべての依存jarのバージョン番号が表示されます)。すべてが単一のjarファイルに詰まるのを避けます)。
http://fiji.sc/Uber-JARは、代替の優れた説明を提供します。
uber-JARを構築するには、3つの一般的な方法があります。
- 陰影なし。すべてのJARファイルを解凍し、それらを単一のJARに再パックします。
- プロ:Javaのデフォルトのクラスローダーで動作します。
- 欠点:同じパスを持つ複数のJARファイルに存在するファイル(例:META-INF / services / javax.script.ScriptEngineFactory)は互いに上書きするため、動作に問題が発生します。
- ツール:Mavenアセンブリプラグイン、Classworlds Uberjar
- シェーディング。シェーディングなしと同じですが、すべての依存関係のすべてのパッケージの名前を変更します(つまり、「シェーディング」)。
- プロ:Javaのデフォルトのクラスローダーで動作します。依存関係のバージョンの衝突(すべてではない)の一部を回避します。
- 欠点:同じパスを持つ複数のJARファイルに存在するファイル(例:META-INF / services / javax.script.ScriptEngineFactory)は互いに上書きするため、動作に問題が発生します。
- ツール:Maven Shadeプラグイン
- JARのJAR。最終的なJARファイルには、他のJARファイルが埋め込まれています。
- 長所:依存関係バージョンの衝突を回避します。すべてのリソースファイルが保持されます。
- 欠点:特別な「ブートストラップ」クラスローダーをバンドルして、JavaがラップされたJARファイルからクラスをロードできるようにする必要があります。クラスローダーの問題のデバッグはより複雑になります。
- ツール:Eclipse JAR File Exporter、One-JAR。
META-INF/services
ディレクトリ下のファイルのコンテンツを連結するためのものです。詳細はこちら:maven.apache.org/plugins/maven-shade-plugin/examples/…–
<!-- 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>
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を脇に置いて、JARライブラリーをメインJar内に置くことができますが、独自のクラスローダーを使用する必要があります。
このプロジェクトをチェック:One-JAR リンクテキスト
この投稿は少し古いかもしれませんが、最近同じ問題が発生しました。John Staufferによって提案された最初の解決策は良い解決策ですが、私はこの春に働いているときにいくつかの問題を抱えていました。私が使用するSpringのdependency-jarには、同じパスと名前を共有するいくつかのプロパティファイルとxml-schemas宣言があります。これらのjarは同じバージョンのものですが、jar-with-dependencies maven-goalは、最後に見つかったファイルでこれらのファイルを上書きしていました。
最終的に、Spring jarが正しいプロパティファイルを見つけられなかったため、アプリケーションを起動できませんでした。この場合、Ropによって提案されたソリューションは私の問題を解決しました。
また、それ以来、spring-bootプロジェクトが存在するようになりました。パッケージの目標をオーバーロードし、独自のクラスローダーを提供するMavenの目標を提供することで、この問題を管理する非常に優れた方法があります。spring-bootsリファレンスガイドを参照してください。
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>
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>