0

質問があります。私は、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 にキャストすることです...

4

1 に答える 1

0

問題が解決しました!正しいクラスローダーを使用していません。

                            ClassLoader STAFLoader = MyCurrentClass.class.getClassLoader();

                            URLClassLoader URLLoader = new URLClassLoader(jarUrl, STAFLoader);

                            Class iInterfaceClass = Class.forName(classname, true, URLLoader);

最初の行は問題を解決しました。

于 2010-09-16T15:16:43.690 に答える