質問があります。私は、STAF サービスを実装する Java プログラムを作成しました (テスト用の単なるフレームワーク、http://staf.sourceforge.net/ )。STAF の場合、すべてのクラスはディレクトリ STAF-INF/classes にある必要があります。そこで、プログラムを次のような JAR ファイル MyProg.jar にパックしました。
MyProg.jar
--> STAF-INF/
-------> classes/
------------> com/
----------------->/MyClass.class
----------------->/IInterface.class
---> META-INF/
したがって、私の JAR-Archiv には 2 つのディレクトリがあり、1 つは META-INF と呼ばれ、STAF-INF と呼ばれます。STAF-INF には、classes という別のディレクトリがあり、classes には、私のクラスと私のインターフェイスを含むパッケージ "com" があります。それが状況です。これは非常にうまく機能し、ディレクトリ構造は私が使用する STAF フレームワークに必要です。
ここで問題が発生します。他のユーザーが私の JAR ファイル (MyProg.jar) を取得し、それを自分のプロジェクトに含めて、私のインターフェイス IInterface を実装するクラスを作成できるようにしたいと考えています。
問題 1) MyProg.jar ファイルを Eclipse-Java-Project に追加すると、IInterface が見つかりません。JARファイルにパッケージが見つからない場合でも。ディレクトリ(STAF-INF/classes)と関係があると思いますか???
問題 2) Eclipse で新しいプロジェクトを古い MyProg プロジェクトに接続すると、Eclipse が IInterface を検出し、それを実装できます (これは問題 1 の回避策になる可能性がありますが、:)。次に、新しいクラスを JAR ファイルとしてエクスポートします。これを NewClassForMyProg.jar と呼びましょう。しかし、MyProg プログラムの NewClassForMyProg.jar から新しいクラスをロードすると、例外が発生しました。
NoClassDefFoundError: com.IInterface
これも私のディレクトリと関係があると思います。しかし、よくわかりません。URLClassLoaderまたはClassPathにも問題がある可能性があると思います...しかし、わかりません...
助けてください。ありがとう。
編集:
クラスをロードするメソッドのコードは次のとおりです。
public static ArrayList<IInterface> getExternalWorkloads(String jarName, String packageName)
{
jarName = "c:/STAF/services/NewClassForMyProg.jar";
packageName = "com";
packageName = packageName.replaceAll("\\." , "/");
ArrayList<IInterface> myClasses = new ArrayList<IInterface>();
JarInputStream jarFile = null;
JarEntry jarEntry = null;
try
{
jarFile = new JarInputStream(new FileInputStream (jarName));
while(true)
{
jarEntry=jarFile.getNextJarEntry();
if(jarEntry == null)
break;
if((jarEntry.getName ().startsWith (packageName)) &&
(jarEntry.getName ().endsWith (".class")))
{
String classname = jarEntry.getName().replaceAll("/", "\\.");
classname = classname.substring(0, classname.length() - 6);
if(classname.contains("$") == false)
{
ClassLoader.getSystemClassLoader();
URL url = new URL("jar:file:" + jarName + "!/");
URLClassLoader ucl = new URLClassLoader(new URL[] { url });
try
{
Class<IInterface> myLoadedClass = (Class<IInterface>) ucl.loadClass(classname);
IInterface myClass = (IInterface) myLoadedClass.newInstance();
myClasses.add(myClass);
}
catch(Exception e){}
}
}
}
jarFile.close();
}
catch(Exception e){}
return myClasses;
}
ああ、そのメソッドでクラスをロードすると、それは自分の JAR (MyProg.jar) 内にあり、完璧に動作します。しかし、他の JAR (NewClassForMyProg.jar" など) ではエラーが発生します。しかし、メソッドはクラスを見つけます。問題は、新しいインスタンスを作成して IInterface にキャストすることです...