我有一个问题:我编写了一个实现 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 ...