Method to dynamically load java class files
I believe it's a ClassLoader
you're after.
I suggest you start by looking at the example below which loads class files that are not on the class path.
// Create a File object on the root of the directory containing the class file
File file = new File("c:\\myclasses\\");
try {
// Convert File to a URL
URL url = file.toURI().toURL(); // file:/c:/myclasses/
URL[] urls = new URL[]{url};
// Create a new class loader with the directory
ClassLoader cl = new URLClassLoader(urls);
// Load in the class; MyClass.class should be located in
// the directory file:/c:/myclasses/com/mycompany
Class cls = cl.loadClass("com.mycompany.MyClass");
} catch (MalformedURLException e) {
} catch (ClassNotFoundException e) {
}
How to dynamically load a Java class without using a class loader?
Disclaimer: I'm involved with JRebel development
Technically, it is possible to bypass the classloader with some Unsafe magic, and JVM leverages that with lambdas when creating the runtime anonymous classes (in Java 8).
However, JRebel actually integrates with the existing classloaders and doesn't create new ones - that's what the slide mean. JRebel doesn't drop the existing classloader when it has to reload a class. Instead, it loads and versions the classes within the existing classloaders.
Best approach to dynamically load modules (classes) in Java
It sounds like you might want to use the ServicerLoader interface, which has been available since Java 6. However, bear in mind that, if you want to use Spring dependency injection, this is probably not what you want.
Dynamic class-loading from specific folder
since you have ...\bin\Encrypt
is the folder where you classes are i would bet the package for your classes is Encrypt
. in this case abc
should be
String abc = "Enrcypt.Class1";
if the classes are in the default package which means they have no package declaration than use
String abc = "Class1";
note also that there is no need for the extension .class
in the name of the class.
To call the a method of class loaded this way you should refer to java refelction api.
first get a Method object from Class cl
using getMethod
than use that method object's method invoke to call the function. you'll need to provide an instance of the Class dynamically loaded if the the method to call is not static, if it is static just pass null.
Dynamically load a Class and invoke a method in Java
Looks good to me.
If you're doing a lot of reflection-related code you might look at Apache Beanutils or Apache OGNL or something similar.
How do you dynamically compile and load external java classes?
Take a look at JavaCompiler
The following is based on the example given in the JavaDocs
This will save a File
in the testcompile
directory (based on the package
name requirements) and the compile the File
to a Java class...
package inlinecompiler;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class InlineCompiler {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(64);
sb.append("package testcompile;\n");
sb.append("public class HelloWorld implements inlinecompiler.InlineCompiler.DoStuff {\n");
sb.append(" public void doStuff() {\n");
sb.append(" System.out.println(\"Hello world\");\n");
sb.append(" }\n");
sb.append("}\n");
File helloWorldJava = new File("testcompile/HelloWorld.java");
if (helloWorldJava.getParentFile().exists() || helloWorldJava.getParentFile().mkdirs()) {
try {
Writer writer = null;
try {
writer = new FileWriter(helloWorldJava);
writer.write(sb.toString());
writer.flush();
} finally {
try {
writer.close();
} catch (Exception e) {
}
}
/** Compilation Requirements *********************************************************************************************/
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
// This sets up the class path that the compiler will use.
// I've added the .jar file that contains the DoStuff interface within in it...
List<String> optionList = new ArrayList<String>();
optionList.add("-classpath");
optionList.add(System.getProperty("java.class.path") + File.pathSeparator + "dist/InlineCompiler.jar");
Iterable<? extends JavaFileObject> compilationUnit
= fileManager.getJavaFileObjectsFromFiles(Arrays.asList(helloWorldJava));
JavaCompiler.CompilationTask task = compiler.getTask(
null,
fileManager,
diagnostics,
optionList,
null,
compilationUnit);
/********************************************************************************************* Compilation Requirements **/
if (task.call()) {
/** Load and execute *************************************************************************************************/
System.out.println("Yipe");
// Create a new custom class loader, pointing to the directory that contains the compiled
// classes, this should point to the top of the package structure!
URLClassLoader classLoader = new URLClassLoader(new URL[]{new File("./").toURI().toURL()});
// Load the class from the classloader by name....
Class<?> loadedClass = classLoader.loadClass("testcompile.HelloWorld");
// Create a new instance...
Object obj = loadedClass.newInstance();
// Santity check
if (obj instanceof DoStuff) {
// Cast to the DoStuff interface
DoStuff stuffToDo = (DoStuff)obj;
// Run it baby
stuffToDo.doStuff();
}
/************************************************************************************************* Load and execute **/
} else {
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
System.out.format("Error on line %d in %s%n",
diagnostic.getLineNumber(),
diagnostic.getSource().toUri());
}
}
fileManager.close();
} catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException exp) {
exp.printStackTrace();
}
}
}
public static interface DoStuff {
public void doStuff();
}
}
Now updated to include suppling a classpath for the compiler and loading and execution of the compiled class!
Java Dynamically Loading a class
The constructor of URLClassLoader takes an array of URLs, not a single URL.
Related Topics
Java Wait for Thread to Finish
How to Enumerate All Classes in a Package and Add Them to a List
Replace the Last Part of a String
Java 8 Instant.Now() with Nanosecond Resolution
Java Division by Zero Doesnt Throw an Arithmeticexception - Why
Comparing Float/Double Values Using == Operator
Drawing an Object Using Getgraphics() Without Extending Jframe
What Does an Assignment Expression Evaluate to in Java
Running Multiple Launch Configurations at Once
"Int Cannot Be Dereferenced" in Java
In Java, When Does an Object Become Unreachable
How to Flatten 2D Array to 1D Array
Get the Changed HTML Content After It's Updated by JavaScript? (Htmlunit)
Getting a Illegalblocksizeexception: Data Must Not Be Longer Than 256 Bytes When Using Rsa