Scripting java : import a class from an external file
I want to import a class that I already write in an external folder,
for example :
My class Example.java
that is located in c:\class\Example.java
to my script like using
var importedClass = new JavaImporter("c:\\class\\Examp开发者_如何转开发le.java");
or
importClass("c:\\class\\Example.java");
this is in a script for ScriptEngine rhino
how can I do that ???I understand that you want to:
- Compile a Java source file
- Load the compiled code
- Use the resultant class in some JavaScript
The javax.tools package provides a mechanism for compiling code, though if you're not running in a JDK, ToolProvider.getSystemJavaCompiler() will return null
and you'll have to rely on some other compilation mechanism (invoking an external compiler; embedding the Eclipse compiler; etc.).
Java bytecode (.class
binaries) can be loaded at runtime via ClassLoaders.
In order for the loaded classes to be visible to your scripting engine, you'll need to provide them via the ScriptEngineManager(ClassLoader) constructor.
EDIT: based on the requirements
public class HelloWorld {
public void say() {
System.out.println("Hello, World!");
}
}
This script just invokes the Java reflection API to load and instantiate a class HelloWorld.class
from the C:\foo\bin
directory:
function classImport() {
var location = new java.net.URL('file:/C:/foo/bin/');
var urlArray = java.lang.reflect.Array.newInstance(java.net.URL, 1);
urlArray[0] = location;
var classLoader = new java.net.URLClassLoader(urlArray);
return classLoader.loadClass("HelloWorld");
}
var myClass = classImport();
for(var i=0; i<10; i++) {
myClass.getConstructor(null).newInstance(null).say();
}
There are more elegant ways of doing this, I'm sure.
I would question why do this.
The solutions listed here will work. The problem is going to be that:
- You will have a cobbled together solution with reflection that will be hard to troubleshoot.
- Are your customers Okay with patching code that is loaded at Runtime ? Everyplace I have worked at is not.
If I understand you correctly, what you are actually trying to do is load Java classes so that you can (presumably) create instances, etcetera. The term for this is dynamic loading not importing.
Java allows you to dynamically load bytecode files (*.class
) using the ClassLoader.loadClass(String)
method. There are lots of resources on this topic; e.g. the "Class Loading" page from the JNDI tutorial. Be prepared to spend some time getting your head around this topic. In particular, since you are trying to load a class that is not on your application's normal classpath, you will need to create a new classloader to do this. The Javadocs for the java.lang.ClassLoader
class are here.
Java source code cannot be directly loaded, but must first be compiled using a Java compiler. If you are using a modern JDK installation, it is possible to call the Java compiler at runtime. But a JRE installation does not include a Java compiler. If your platform has a Java compiler available at runtime, you can access it via the getSystemJavaCompiler()
static method of the ToolProvider
class. Once again, calling the Java compiler from within a running Java application is complicated.
精彩评论