2

編集:これはプロジェクトのセットアップです:

IDE: エクリプス:

Project1 : 「サーバー」

src:
com/mainpackage/main.java
libs:
commons-x-0.jar
PluginInterface.jar

libs-folder 内のすべての jar はビルドパスにあります。

Project2 : 「プラグインインターフェース」

src:
com/interfaces/plugininterface

Project3 : 「プラグイン」

src:
com/package/class1.java - (this implements plugininterface)
libs:
library1.jar
PluginInterface.jar

libs-folder 内のすべての jar はビルドパス上にあります

そのため、プラグイン (Project3) をエクスポートすると、このような jar が取得されます (エクスポートから PluginInterface.jar が除外されます)。

com/
com/package/
com/package/class1.class
com/package/class1.java
libs/
libs/library1.jar

library1.jar は次のようになります。これは私が書いたものではありません。

com/
com/stuff/
com/stuff/libclass.java
com/stuff/libclass.class

今、私はインターフェイスを介して「サーバー」でclass1を利用したい:

ClassLoader loader=URLClassLoader.newInstance( 
                new URL[]{new URL("file:path/to/plugin.jar")},
                ClassLoader.getSystemClassLoader()
        );

Class<?> pluginclass = Class.forName("com.package.class1", true, loader);
plugininterface ref = (plugininterface)pluginclass.newInstance();

どちらのプロジェクトもビルドパスに「PluginInterface.jar」が含まれているため、両方のプロジェクトが知っているインターフェイスを使用して、class1 からメソッドを呼び出すことができます。

問題:

「サーバー」は「libclass」を認識しません。これは、そのパスに含まれておらず、library1 がネストされている plugin.jar からクラスをロードしなかったためです。

サーバーでライブラリとしてインポートできない場合、このクラスにアクセスするにはどうすればよいですか?

助けてくれてありがとう!

編集:誰かがこの問題を再び抱えた場合のために、それを機能させるANTファイルのビルドターゲットを追加します:

<target name="build">
     <javac destdir="bin" includeantruntime="false" source="1.7" target="1.7">
        <src path="src"/>
        <classpath refid="Plugin.classpath"/>
     </javac>
    <unzip src="${libs}/library1.jar" dest="bin/">
        <patternset>
            <include name="**/*.class"/>
        </patternset>
</unzip>
    <jar destfile="plugin.jar" basedir="bin"></jar> 
</target>

Library-jar の内容をビルド ディレクトリ (私の場合は ./bin/) にコピーするだけです。ライブラリクラスをクラスローダーに供給する必要さえありません。クラスをロードするときにそれらを使用します。

4

2 に答える 2

11

標準クラス・ローダーは、ネストされた jar ファイルをサポートしていません。プログラムでjarファイルを抽出するか、ネストされたファイルをオンデマンドで解凍する独自のクラスローダーを作成できます。ただし、流れに逆らって泳ぐことになります。そのようなパッケージングは​​お勧めできません。代わりに、ネストされた jar をその親に分解することをお勧めします。これは、たとえば、Maven 依存関係プラグインが行うことであり、Leiningen で Clojure アプリケーションを公開するデフォルトの方法です。

Eclipse から目標を達成するには、次の方法が最適です。

  1. Eclipse の Export JAR ウィザードで、JAR をビルドするために内部で生成された Ant ビルド スクリプトを保存します。

  2. 結果のスクリプトを特定のニーズに合わせて調整します。

  3. 今後はウィザードを実行せず、ant スクリプトを実行します。

于 2013-06-24T12:00:25.080 に答える