我有一个问题:我编写了一个实现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 ...
答案 0 :(得分:0)
ClassLoader STAFLoader = MyCurrentClass.class.getClassLoader();
URLClassLoader URLLoader = new URLClassLoader(jarUrl, STAFLoader);
Class iInterfaceClass = Class.forName(classname, true, URLLoader);
第一行解决了这个问题。