简体   繁体   English

Java:动态加载外部类

[英]Java: Dynamically loading external classes

I am writing an application that will load Java scripts. 我正在编写一个将加载Java脚本的应用程序。 I currently have a GUI which utilizes a JFileChooser to allow the user to select a script from their machine. 我目前有一个GUI,该GUI利用JFileChooser允许用户从其计算机中选择脚本。 The script file can be anywhere. 脚本文件可以在任何地方。 It is not on the classpath. 它不在类路径上。 Having only a File object to represent that script file, how can I obtain a Class representation of it? 只有一个File对象来表示该脚本文件,我如何获得它的Class表示形式?

I know that to load a class you need its binary name, so in.this.format . 我知道要加载一个类,您需要它的二进制名称,即in.this.format However, the problem with that is I don't know how the script writer may have packaged it. 但是,这样做的问题是我不知道脚本编写者如何打包它。 For example, he/she may have, while developing it, put the script file in the package foo.bar . 例如,他/她在开发脚本时可能会将脚本文件放入包foo.bar After I download this script and place it in my documents (ie, not in foo/bar ), I can't load the script without knowing that it was packaged in foo.bar . 下载此脚本并将其放在我的文档中后(即不在 foo/bar ),在不知道脚本已打包在foo.bar情况下无法加载该脚本。 If the class name is Test and I try to create a URLClassLoader pointing to the script file by doing new URLClassLoader(new URL[] { new URL(scriptFile.toURI().toURL()) }) and I do classLoader.loadClass("Test") I will get an exception saying that the class had the wrong name, and the correct name is foo.bar.Test . 如果类名是Test ,我尝试创建一个URLClassLoader做指向脚本文件new URLClassLoader(new URL[] { new URL(scriptFile.toURI().toURL()) })和我做classLoader.loadClass("Test")我将得到一个异常,说该类的名称错误,而正确的名称是foo.bar.Test But how am I supposed to know that ahead of time? 但是我应该如何提前知道呢?

This is what I have right now: 这就是我现在所拥有的:

public class ScriptClassLoader extends URLClassLoader {

    private final File script;

    public ScriptClassLoader(File script) throws MalformedURLException {
        super(new URL[] { script.toURI().toURL() });
        this.script = script;
    }

    public Class<?> load() throws ClassNotFoundException {
        String fileName = script.getName();
        String className = fileName.substring(0, fileName.indexOf(".class"));
        return loadClass(className);
    }
}

How do people load scripts at runtime that are not part of the program's classpath, and the binary name of the class is not known? 人们如何在运行时加载不属于程序的类路径的脚本,并且该类的二进制名称未知?

If you just need to load a class from a given .class file, no matter how this classes is named, you can load the data yourself and then call ClassLoader's defineClass() method: 如果您只需要从给定的.class文件中加载一个类,则无论此类的命名方式如何,您都可以自己加载数据,然后调用ClassLoader的defineClass()方法:

RandomAccessFile raf = new RandomAccessFile(script, "r");
try {
    byte[] classData = new byte[(int) raf.length()];
    raf.readFully(classData);
    return super.defineClass(null, classData, 0, classData.length);
} finally {
    raf.close();
}

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

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