如何从实现我的界面的JAR-archive中加载一个类? (Java)的

时间:2010-09-15 12:16:18

标签: java jar classloader noclassdeffounderror

我有一个问题:我编写了一个实现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的目录,在类中有我的包“com”,它包含我的类和我的接口。就是这种情况。这个东西非常好用,我使用的STAF框架需要目录结构。

现在,问题出现了: 我希望其他用户可以使用我的JAR文件(MyProg.jar)并将其包含在自己的项目中,以编写实现我的接口IInterface的类。

问题1)当我将MyProg.jar文件添加到Eclipse-Java-Project时,它找不到IInterface。如果甚至在JAR文件中找不到任何包。我认为gots与目录(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 ...

1 个答案:

答案 0 :(得分:0)

问题解决了!我没有使用正确的类加载器。

                            ClassLoader STAFLoader = MyCurrentClass.class.getClassLoader();

                            URLClassLoader URLLoader = new URLClassLoader(jarUrl, STAFLoader);

                            Class iInterfaceClass = Class.forName(classname, true, URLLoader);
第一行解决了这个问题。