[英]How can I load a class from a JAR-archive which implements my interface? (java)
I got a question: I have written a Java program that implements a STAF service (just a framework for testing, http://staf.sourceforge.net/ ). 我有一个问题:我编写了一个实现STAF服务的Java程序(只是一个测试框架, http://staf.sourceforge.net/ )。 For STAF, all my Classes have to be in an Directory STAF-INF/classes.
对于STAF,我所有的类都必须位于目录STAF-INF / classs中。 So I packed my program to an JAR-file MyProg.jar, that looks like this:
因此,我将程序打包到一个JAR文件MyProg.jar中,如下所示:
MyProg.jar
--> STAF-INF/
-------> classes/
------------> com/
----------------->/MyClass.class
----------------->/IInterface.class
---> META-INF/
So, my JAR-Archiv got two directories, one called META-INF and called STAF-INF. 因此,我的JAR-Archiv有两个目录,一个名为META-INF,另一个名为STAF-INF。 In STAF-INF, there is another directory called classes, and in classes there is my package "com" that contains my class and my interface.
在STAF-INF中,还有另一个名为类的目录,并且在类中有我的包“ com”,其中包含我的类和接口。 that's the situation.
就是这种情况。 this thing works very good, andthe directory structure is required by the STAF framework I use.
这个东西工作得很好,并且目录结构是我使用的STAF框架所必需的。
Now, here comes the problem: I want that other users can take my JAR-file (MyProg.jar) and include it to there own project to write classes that implements my interface IInterface. 现在,问题来了:我希望其他用户可以将我的JAR文件(MyProg.jar)包含到自己的项目中,以编写实现我的接口IInterface的类。
Problem 1) When I add the MyProg.jar file to a Eclipse-Java-Project it don't find the IInterface. 问题1)当我将MyProg.jar文件添加到Eclipse-Java-Project时,找不到IInterface。 If even don't find any package in the JAR-file.
甚至在JAR文件中都找不到任何包。 I think that gots something to do with the directories (STAF-INF/classes)???
我认为这与目录(STAF-INF / classes)有关?
Problem 2) When I connect my new project in Eclipse, with my old MyProg-project, Eclipse finds the IInterface and I can implement it (this could be a workaround for problem 1, but:). 问题2)当我在Eclipse中将新项目与旧的MyProg项目连接时,Eclipse找到了IInterface并可以实现它(这可能是问题1的解决方法,但是:)。 Then I export my new class as a JAR-file, let's call it NewClassForMyProg.jar.
然后,我将新类导出为JAR文件,我们将其称为NewClassForMyProg.jar。 But when I load the new class out of the NewClassForMyProg.jar in my MyProg-program I got an exception:
但是,当我从MyProg程序的NewClassForMyProg.jar中加载新类时,出现了一个异常:
NoClassDefFoundError: com.IInterface NoClassDefFoundError:com.IInterface
I think this got something to do with my directories, too. 我认为这也与我的目录有关。 but i am not sure.
但我不确定。 I think it could be a problem with the URLClassLoader or the ClassPath, too... but i have no idea...
我认为URLClassLoader或ClassPath也可能是一个问题...但是我不知道...
please help. 请帮忙。 thanx.
谢谢。
edit: 编辑:
here's the code of the method that should load the classes: 这是应该加载类的方法的代码:
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;
}
Oh, and if I load with that method a class, that is inside my own JAR (MyProg.jar) it works perfect. 哦,如果我使用该方法加载一个类,那么该类在我自己的JAR(MyProg.jar)内部,则效果很好。 But by a other JAR (like NewClassForMyProg.jar") I get an Error. But the method founds the classes, the problem is to make a new instance and cast it to IInterface...
但是通过另一个JAR(例如NewClassForMyProg.jar“),我得到一个错误。但是该方法找到了类,问题是要创建一个新实例并将其转换为IInterface ...
problem solved! 问题解决了! I haven't used the correct classloader.
我没有使用正确的类加载器。
ClassLoader STAFLoader = MyCurrentClass.class.getClassLoader();
URLClassLoader URLLoader = new URLClassLoader(jarUrl, STAFLoader);
Class iInterfaceClass = Class.forName(classname, true, URLLoader);
the fist line solved the problem. 拳头线解决了这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.