简体   繁体   English

如何使用 URLClassLoader 加载 *.class 文件?

[英]How to use URLClassLoader to load a *.class file?

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它存在于 /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) (所以它必须是一个可以被类加载器加载的正确的 .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$1.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:我的问题:

  1. What am I doing wrong above?我在上面做错了什么? How do I fix it?我如何解决它?
  2. Is there a way to load several class files and iterate over them?有没有办法加载几个类文件并遍历它们?

From the Javadocs for the URLClassLoader(URL[]) constructor :URLClassLoader(URL[])构造函数Javadocs

Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader.使用默认委托父类加载器为指定的 URL 构造一个新的 URLClassLoader。 The URLs will be searched in the order specified for classes and resources after first searching in the parent class loader.在父类加载器中首次搜索后,将按照为类和资源指定的顺序搜索 URL。 Any URL that ends with a '/' is assumed to refer to a directory.任何以“/”结尾的 URL 都被假定为指向一个目录。 Otherwise, the URL is assumed to refer to a JAR file which will be downloaded and opened as needed.否则,该 URL 被假定为引用一个 JAR 文件,该文件将根据需要被下载和打开。

So you have two options:所以你有两个选择:

  1. Refer to the directory that the .class file is in参考.class文件所在的目录
  2. Put the .class file into a JAR and refer to that将 .class 文件放入 JAR 并引用该文件

(1) is easier in this case, but (2) can be handy if you're using networked resources. (1) 在这种情况下更容易,但如果您使用网络资源,则 (2) 会很方便。

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是的,您可以根据需要加载任意数量的类

您必须通过提供完全限定的类名来加载类,该类名是类名,其包路径为,

Class c = ucl.loadClass("com.mypackage.IndependentClass");

I was having a similar problem but my class file was residing inside a package named "customElements".我遇到了类似的问题,但我的类文件驻留在名为“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.在这种情况下,URL 需要构建到根包正上方的文件夹,并且在 load 方法中,应该传递包括包在内的类的完整名称。 For example, in my case;例如,就我而言; URL was like:网址是这样的:

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 是我的类加载器。

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.这为您提供了 jar 和类路径。 From here you are able to manage your process.从这里您可以管理您的流程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM