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 有两个目录,一个叫 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 回答