Table of Contents

Java - Dynamic Java code execution (at runtime)

About

How to create, compile and run Java code at runtime making it a dynamic, scripting language.

The below section is showing parts of the whole script highlighting all the steps needed to create and run dynamic java code.

You can find the whole script at DynamicRuntimeExecutionTest.java

The sample dynamic code is a simple class with a static method that prints Hello Nico

public class java demo {
     public static void run() {
             System.out.println("Hello Nico"); 
    }
}

Steps

Creating the java source file

final String className = "javademo";
Path temp = Paths.get(System.getProperty("java.io.tmpdir"), className);
Files.createDirectories(temp);
Path javaSourceFile = Paths.get(temp.normalize().toAbsolutePath().toString(), className + ".java");
System.out.println("The java source file is loacted at "+javaSourceFile);
String code = "public class " + className + " {" +
		"public static void run() {\n" +
		"       System.out.println(\"Hello Nico\"); \n" +
		"    }" +
		"}";
Files.write(javaSourceFile, code.getBytes());

Compiling the source to create a class file

The java compiler library is located at javase/9/docs/api/javax/tools/JavaCompiler.html. It is javase/9/docs/api/javax/tools/Tool.html (bundled in

/lib/tools.jar'') A tool is a common interface tools that can be invoked from a program.

For Java 10, see Java 10

final String toolsJarFileName = "tools.jar";
final String javaHome = System.getProperty("java.home");
Path toolsJarFilePath = Paths.get(javaHome, "lib", toolsJarFileName);
if (!Files.exists(toolsJarFilePath)){
	System.out.println("The tools jar file ("+toolsJarFileName+") could not be found at ("+toolsJarFilePath+").");
}
// Definition of the files to compile
File[] files1 = {javaSourceFile.toFile()};
// Get the compiler
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// Get the file system manager of the compiler
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
// Create a compilation unit (files)
Iterable<? extends JavaFileObject> compilationUnits =
		fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files1));
// A feedback object (diagnostic) to get errors
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
// Compilation unit can be created and called only once
JavaCompiler.CompilationTask task = compiler.getTask(
		null,
		fileManager,
		diagnostics,
		null,
		null,
		compilationUnits
);
// The compile task is called
task.call();
// Printing of any compile problems
for (Diagnostic diagnostic : diagnostics.getDiagnostics())
	System.out.format("Error on line %d in %s%n",
			diagnostic.getLineNumber(),
			diagnostic.getSource());

// Close the compile resources
fileManager.close();
Load and run the class
ClassLoader classLoader = DynamicRuntimeExecutionTest.class.getClassLoader();
URLClassLoader urlClassLoader = new URLClassLoader(
		new URL[] { temp.toUri().toURL() },
		classLoader);
Class javaDemoClass = urlClassLoader.loadClass(className);
Method method = javaDemoClass.getMethod("run");
method.invoke(null); // null because this is a static method

Result:

Hello Nico