Method to Dynamically Load Java Class Files

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



Leave a reply



Submit