3

数時間後、大量のドキュメントと SO の質問を読んだ後でさえ、私は機知に富んでいます。明らかな何かが欠けていることは確かですが、それを理解することはできません。

メイン メソッドを持つ単一のエントリ ポイントを含む、多数の Java ファイルを作成しました。このクラスは、jar ファイル mylib.jar 内の com.test.lib.MyLibraryClass.class にある 1 つの「ライブラリ」クラスも使用します。次の ant XML を使用して jar ファイルを正常に構築しています。

<target name="jar" depends="compile">
        <jar destfile="${jar.dir}/${jar.name}.jar">
            <fileset dir="${classes.dir}" />
            <fileset dir="${lib.dir}" />
            <manifest>
                <attribute name="Main-Class" value="${main-class}" />
                <attribute name="Class-Path" value="mylib.jar"/>
            </manifest>
        </jar>
    </target>

そのターゲットを実行して作成された jar を調べると、.class ファイルと mylib.jar がすべて含まれていることがわかります。

ただし、jar を実行しようとすると、次のエラーが発生します。

Exception in thread "main" java.lang.NoClassDefFoundError: com/test/lib/MyLibraryClass
    at com.mytest.MyMain.<init>(Unknown Source)
    at com.mytest.MyMain.main(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.test.lib.MyLibraryClass
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 2 more

何を変更する必要がありますか? 不正な形式または不完全なマニフェストを生成していますか?

どうもありがとう!

4

2 に答える 2

4

問題は、標準のクラスローダーが別のJAR内にあるJAR内にあるクラスを見つけることができないことです。Class-Pathマニフェスト変数は、実際にmylib.jarは、現在のディレクトリ内のファイルをクラスパスに追加するようにJVMに指示しています。

3つの解決策があります:

  • mylib.jarファイルを見つけられる場所に置きます(それに応じてマニフェストプロパティを設定します。

  • メインJARのクラスと関連するすべてのライブラリJARを1つのJARファイルに結合するUber-jarを作成します。

  • JAR-in-a-JARからロードする方法を知っているファンキーなクラスローダーを作成し、クラスローダーをインスタンス化して使用するようにアプリケーションを変更します。(このアプローチはお勧めしません...)

最初の2つの方法は、JAR-in-a-JAR構造をさまざまな方法で取り除くことで問題を解決することに注意してください。

于 2012-10-01T06:46:57.917 に答える
2

コマンドで実行しようとしている場合java、これは jar 内への jar の埋め込みをサポートしていません。マニフェスト内のそのエントリを使用して、クラス ローダーは、Jar 内ではなく、クラスを起動しているベース フォルダー内で jar を探します。mylib.jarベースフォルダーに入れjavaて -cp mylib.jar` オプションを指定して実行するか、jar が埋め込まれた jar の実行をサポートするツールを使用できます。これまたは Google の「jars within jar」を参照すると、大量のヒットが表示されます。

于 2012-10-01T06:43:57.543 に答える