web-dev-qa-db-ja.com

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

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

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

最終的なJARファイルには、.m2フォルダー内のMaven階層のようなフォルダーの形式で依存関係を配置するmaven-shade-pluginとは異なり、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.

この例外を修正するにはどうすればよいですか?

91
Mahmoud Saleh

このリンクをたどる:

方法:Eclipse Mavenが依存関係のあるビルドjarをインストールする

クラスローダーがjar内からjarをロードしないため、これは実行可能なソリューションではないことがわかりました。そのため、jar内の依存関係をアンパックすると思います。

6
Mahmoud Saleh

以下は私の解決策です。動作するかどうかをテストします。

<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ファイルの問題は続きます。私はそれが誰かを助けることを願っています。

73
gmode

更新しました:

<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> 
27
Ahmet Karakaya

最も簡単で効率的な方法は、次のような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ファイルですべてを非正規化します。

23
Andrey Borisov

executable packer maven plugin は、まさにその目的に使用できます。すべての依存関係を含むスタンドアロンJavaアプリケーションを特定のフォルダーのJARファイルとして作成します。

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

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

12
Cybran

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

    <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
3
Eduardo Andrade

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

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

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

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

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

=============はい、これは古いスレッドであることは知っていますが、検索結果でまだ高いので、私のような人を助けるかもしれないと思いました。

2
user4815755

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

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

1
Radu Murzea