Mavenを使用して、必要なすべてのJARファイルを最終的なJARファイル内のライブラリフォルダーに配置するにはどうすればよいですか?


104

私はスタンドアロンアプリケーションでMavenを使用していて、ここにある回答の1つにあるように、ライブラリフォルダー内のJARファイルにすべての依存関係をパッケージ化したいと思います。

Mavenを使用して、依存関係を持つ実行可能JARを作成するにはどうすればよいですか?

私の最終的なJARファイルには、依存関係をmaven-shade-plugin.m2フォルダーのMaven階層のようなフォルダーの形式で配置するものとは異なり、依存関係をJARファイルとして含むライブラリフォルダーが必要です。

ええと、実際には現在の構成で十分ですが、アプリケーションの実行時に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プラグインを好むかもしれませんか?
Andrey Borisov

例外メッセージはPOMファイルと比較して古くなっていますか?メインクラスcom.myapp.MainClassが検索されているようcom.tastycafe.MainClassです。
Duncan Jones

@ダンカンジョーンズ、コピーペーストの問題、私は質問を編集しました
Mahmoud Saleh

3
jar内にjarが必要な場合、Javaの標準クラスローダーはそれらを理解できません。
するThorbjörnRavnアンデルセン

mavenの依存関係をlibフォルダーに配置するが、JARの外部に配置する方法は?
ed22、2018

回答:


81

以下は私の解決策です。それがあなたのために働くかどうかそれをテストしてください:

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

最初のプラグインはすべての依存関係をtarget / classes / libフォルダーに入れ、2番目のプラグインはライブラリフォルダーを最終的なJARファイルに含めて、Manifest.mfファイルを構成します。

ただし、JARファイルをロードするには、カスタムクラスロードコードを追加する必要があります。

または、カスタムクラスロードを回避するために、「$ {project.build.directory} / libを使用できますが、この場合、最終的なJARファイル内に依存関係がなく、目的を達成できません。

質問されてから2年になります。それでもネストされたJARファイルの問題は解決しません。誰かのお役に立てば幸いです。


1
使用法:mvn install、cd target、java -jar MyJarFile-1.0.jar
djb

私は何を逃しますか?これにより、「lib /」とすべての単一のjarを含むマニフェストクラスパスエントリがlibフォルダーから作成されます。これは意図されていますか?どうして?
gapvision 2016

2
「$ {project.build.directory} / classes / lib」を$ {project.build.directory} / libに変更した後に機能しました
Rajendra Thorat

1
Unfortunatellyには、規定どおりに宣言された依存関係が含まれています。
Philippe Gioseffi 16

@Rajendra、ありがとう、助けになりました:$ {project.build.directory} / lib
Mindaugas K.

30

更新しました:

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

4
これはlibフォルダーをjar外に置きます(これは私が望んでいるものではありません)。jar内にlibを置くよりも良いですか?この場合、アプリケーションをクライアントに配信する方法は?
Mahmoud Saleh 2012

今はもっとはっきりしています。グーグル検索させてください。しかし、実行可能jarファイル内の指定されたフォルダーにすべての依存関係jarファイルをコピーする理由を知りたいのですが。すべての依存jarファイルがjarファイル内にある場合、それらをlibフォルダーに配置する必要があるのはなぜですか?
アフメットカラカヤ2012

23

最も簡単で最も効率的な方法は、次のようなuberプラグインを使用することです。

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

すべてを1つのJARファイルで非正規化します。


私の現在の設定に加えてそれを使用しますか?そして、このプラグインは正確に何をしますか?
Mahmoud Saleh

15
jarファイルをこのようにしたくありません。すべての依存関係を、netbeanのようにjarファイル内のlibフォルダーに入れたいです。
Mahmoud Saleh 2012

12

実行可能なパッカーのMavenプラグインは、まさにその目的のために使用することができます。特定のフォルダ内のJARファイルなど、すべての依存関係を含む、スタンドアロンのJavaアプリケーションを作成します。

セクションpom.xml内に次のコードを追加するだけ<build><plugins>です(mainClassそれに応じての値を置き換えてください)。

<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、を実行した後ににありますmvn package。コンパイル時および実行時の依存関係はすべてlib/、JARファイル内のフォルダーに含まれます。

免責事項:私はプラグインの作成者です。


私はそれを試してみましたが、私はそれが働いていると言うことができます...あなたが言ったように、このプラグインは、jarファイル内のlibディレクトリにそのライブラリ(jarファイル)とjarファイルを作成します...構成が簡単で、本当に..です 私はそれが何だと思いますこの質問の著者は期待しています...私はあなたに私の投票を与えます...私がそれに見つけた唯一の欠点(それが私がそれを使用できなかった理由です)、私が実行するときに遅延がありますjarとアプリケーションが表示されます(約20秒)。これは、カスタムクラスローダーにライブラリを登録するプロセスが原因であると考えられます...しかし、これは素晴らしいアプローチであり、優れたプラグインです...
Adam M. Gamboa G.


3

ここに私がそれをする方法があります:

    <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
assemblyJARの「target / classes」にあるものは何でも置くだけなので、常に事前にコンパイルを行う必要があることに注意してください。これにより、ソースコードに最近加えた変更がJARに確実に含まれます。したがって、次のようにする必要がありますmvn clean compile assembly:assembly
naXa 2014

2

私は質問に対するこの答えを見つけました:

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

libフォルダー内の依存libファイルを取得するだけでなく、unixとdos実行可能ファイルの両方を含むbinディレクターも取得します。

実行可能ファイルは最終的に、すべての依存ライブラリもリストする-cp引数を指定してjavaを呼び出します。

ロット全体は、ターゲットフォルダー内のappasemblyフォルダーにあります。大作。

=============はいこれは古いスレッドであることはわかっていますが、まだ検索結果が高くなっているので、私のような人に役立つかもしれないと思いました。


1

これは明らかにクラスパスの問題です。IDEの外部でプログラムを実行するときは、クラスパスを少し変更する必要があることを考慮してください。これは、IDEがプロジェクトのルートフォルダを基準にして他のJARをロードするためです。一方、最終的なJARの場合、これは通常は当てはまりません。

これらの状況で私がやりたいのは、JARを手動でビルドすることです。私は最大5分かかり、常に問題を解決します。これを行うことはお勧めしません。Mavenの使用方法を見つけてください。それが目的です。


@SoboLAN JARを手動で構築することは、ここでは解決策ではありません。意図は、「手動」とは正反対のMavenを使用することです。
ダンカンジョーンズ

@DuncanJonesあなたは完全に正しいです。私は彼がMavenを使用してそれを行うことをお勧めします。しかし、私はそれについての経験がなく、どの解決策を推奨すべきか正確に知りませんでした。私はこれを反映するように私の回答を編集しました。
Radu Murzea
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.