編集:これはプロジェクトのセットアップです:
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/) にコピーするだけです。ライブラリクラスをクラスローダーに供給する必要さえありません。クラスをロードするときにそれらを使用します。