115

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

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

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

実際、現在の構成は私が望むことを実行しますが、アプリケーションの実行時に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.

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

4

8 に答える 8

88

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

<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ファイルの問題は解決しません。それが誰かに役立つことを願っています。

于 2014-08-04T10:35:56.857 に答える
34

更新しました:

<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> 
于 2012-08-01T13:02:08.020 に答える
24

最も簡単で効率的な方法は、次のような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-${project.artifactId}-${project.version}</finalName>
            </configuration>
        </plugin>

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

于 2012-08-01T11:57:45.490 に答える
13

実行可能なpackermavenプラグインは、まさにその目的で使用できます。つまり、特定のフォルダーにすべての依存関係を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ファイル内のフォルダーに含まれます。

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

于 2017-05-28T10:16:41.000 に答える
5

このリンクをたどる:

方法:EclipseMavenは依存関係のあるビルドjarをインストールします

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

于 2012-08-01T13:48:24.130 に答える
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
于 2012-08-01T12:36:22.520 に答える
2

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

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

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

実行可能ファイルは、最終的に、依存するすべてのライブラリも一覧表示する-cp引数を使用してjavaを呼び出します。

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

=============はい、これは古いスレッドですが、検索結果の上位に表示されているので、私のような人に役立つかもしれないと思いました。

于 2015-04-21T16:10:27.780 に答える
1

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

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

于 2012-08-01T11:56:54.913 に答える