Java 如何使用 URLClassLoader 加载 *.class 文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/738393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use URLClassLoader to load a *.class file?
提问by
I'm playing around with Reflection and I thought I'd make something which loads a class and prints the names of all fields in the class. I've made a small hello world type of class to have something to inspect:
我正在玩反射,我想我会做一些加载类并打印类中所有字段名称的东西。我做了一个小的 hello world 类型的类来检查一些东西:
kent@rat:~/eclipsews/SmallExample/bin$ ls
IndependentClass.class
kent@rat:~/eclipsews/SmallExample/bin$ java IndependentClass
Hello! Goodbye!
kent@rat:~/eclipsews/SmallExample/bin$ pwd
/home/kent/eclipsews/SmallExample/bin
kent@rat:~/eclipsews/SmallExample/bin$
Based on the above I draw two conclusions:
基于以上,我得出两个结论:
- It exists at /home/kent/eclipsews/SmallExample/bin/IndependentClass.class
- It works! (So it must be a proper .class-file which can be loaded by a class loader)
- 它存在于 /home/kent/eclipsews/SmallExample/bin/IndependentClass.class
- 有用!(所以它必须是一个可以被类加载器加载的正确的 .class 文件)
Then the code which is to use Reflection: (Line which causes an exception is marked)
然后是使用反射的代码:(标记导致异常的行)
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class InspectClass {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
URL classUrl;
classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/IndependentClass.class");
URL[] classUrls = { classUrl };
URLClassLoader ucl = new URLClassLoader(classUrls);
Class c = ucl.loadClass("IndependentClass"); // LINE 14
for(Field f: c.getDeclaredFields()) {
System.out.println("Field name" + f.getName());
}
}
}
But when I run it I get:
但是当我运行它时,我得到:
Exception in thread "main" java.lang.ClassNotFoundException: IndependentClass
at java.net.URLClassLoader.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at InspectClass.main(InspectClass.java:14)
My questions:
我的问题:
- What am I doing wrong above? How do I fix it?
- Is there a way to load several class files and iterate over them?
- 我在上面做错了什么?我如何解决它?
- 有没有办法加载几个类文件并遍历它们?
采纳答案by Michael Myers
From the Javadocs for the URLClassLoader(URL[])
constructor:
从构造函数的JavadocsURLClassLoader(URL[])
:
Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader. The URLs will be searched in the order specified for classes and resources after first searching in the parent class loader. Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be downloaded and opened as needed.
使用默认委托父类加载器为指定的 URL 构造一个新的 URLClassLoader。在父类加载器中首次搜索后,将按照为类和资源指定的顺序搜索 URL。任何以“/”结尾的 URL 都被假定为指向一个目录。否则,该 URL 被假定为引用一个 JAR 文件,该文件将根据需要被下载和打开。
So you have two options:
所以你有两个选择:
- Refer to the directory that the .class file is in
- Put the .class file into a JAR and refer to that
- 参考.class文件所在的目录
- 将 .class 文件放入 JAR 并引用该文件
(1) is easier in this case, but (2) can be handy if you're using networked resources.
(1) 在这种情况下更容易,但如果您使用网络资源,则 (2) 会很方便。
回答by Maurice Perry
You must provide the directories or the jar files containing your .class files to the URLClassLoader:
您必须向 URLClassLoader 提供包含 .class 文件的目录或 jar 文件:
classUrl = new URL("file:///home/kent/eclipsews/SmallExample/bin/");
And yes, you can load as many classes as you like
是的,您可以根据需要加载任意数量的类
回答by CoolCoder
I was having a similar problem but my class file was residing inside a package named "customElements". In such scenarios the URL needs to be constructed till the folder just above the root package and in the load method the complete name of the class including the package should be passed. For example, in my case; URL was like:
我遇到了类似的问题,但我的类文件驻留在名为“customElements”的包中。在这种情况下,URL 需要构建到根包正上方的文件夹,并且在 load 方法中,应该传递包括包在内的类的完整名称。例如,就我而言;网址是这样的:
File customElementsDir = new File("D:/My Space");
//File customElementsDir = new File("D:\customElements");
URL[] urls = null;
try {
URL url = customElementsDir.toURI().toURL();
urls = new URL[] { url };
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And actual loading was like:
实际加载如下:
clazz = childFirstClassLoader
.loadClass("customElements.CustomLoadableClass");
Where childFirstClassLoader is my classloader.
childFirstClassLoader 是我的类加载器。
回答by Suresh
You have to load the class by giving the fully qualified class name that is class name with with its package path as,
您必须通过提供完全限定的类名来加载类,该类名是类名,其包路径为,
Class c = ucl.loadClass("com.mypackage.IndependentClass");
回答by Eduardo IT
I had the same problem but I found this as a solution:
我遇到了同样的问题,但我发现这是一个解决方案:
System.getProperty("java.class.path")
This give you the jar, and classes path. From here you are able to manage your process.
这为您提供了 jar 和类路径。从这里您可以管理您的流程。