简体   繁体   中英

Java: Dynamically loading external classes

I am writing an application that will load Java scripts. I currently have a GUI which utilizes a JFileChooser to allow the user to select a script from their machine. 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?

I know that to load a class you need its binary name, so 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 . After I download this script and place it in my documents (ie, 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 . 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:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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