All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spinal.sim.DynamicCompiler Maven / Gradle / Ivy

The newest version!
package spinal.sim;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Locale;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

/**
 * Dynamic java class compiler and executer  
* Demonstrate how to compile dynamic java source code,
* instantiate instance of the class, and finally call method of the class
*

* http://www.beyondlinux.com * * @author david 2011/07 */ public class DynamicCompiler { /** * where shall the compiled class be saved to (should exist already) */ // private static String classOutputFolder = "/tmp"; public static class MyDiagnosticListener implements DiagnosticListener { public void report(Diagnostic diagnostic) { System.out.println("Line Number->" + diagnostic.getLineNumber()); System.out.println("code->" + diagnostic.getCode()); System.out.println("Message->" + diagnostic.getMessage(Locale.ENGLISH)); System.out.println("Source->" + diagnostic.getSource()); System.out.println(" "); } } /** * java File Object represents an in-memory java source file
* so there is no need to put the source file on hard disk **/ public static class InMemoryJavaFileObject extends SimpleJavaFileObject { private String contents = null; public InMemoryJavaFileObject(String className, String contents) throws Exception { super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); this.contents = contents; } public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return contents; } } /** * Get a simple Java File Object ,
* It is just for demo, content of the source code is dynamic in real use case */ private static JavaFileObject getJavaFileObject() { StringBuilder contents = new StringBuilder( "package math;" + "public class Calculator { " + " public void testAdd() { " + " System.out.println(200+300); " + " } " + " public static void main(String[] args) { " + " Calculator cal = new Calculator(); " + " cal.testAdd(); " + " } " + "} "); JavaFileObject so = null; try { so = new InMemoryJavaFileObject("math.Calculator", contents.toString()); } catch (Exception exception) { exception.printStackTrace(); } return so; } /** * compile your files by JavaCompiler */ public static void compile(Iterable files, String classOutputFolder) { //get system compiler: JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // for compilation diagnostic message processing on compilation WARNING/ERROR MyDiagnosticListener c = new MyDiagnosticListener(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(c, Locale.ENGLISH, null); //specify classes output folder // System.out.println("********** " + System.getProperty("java.class.path")); String separator = System.getProperty("path.separator"); String myPath = DynamicCompiler.class.getProtectionDomain().getCodeSource().getLocation().getPath(); String classpath = System.getProperty("java.class.path") + separator + myPath; Iterable options = Arrays.asList("-d", classOutputFolder, "-classpath", classpath); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, c, options, null, files); Boolean result = task.call(); } /** * run class from the compiled byte code file by URLClassloader */ public static void runIt(String classOutputFolder) { // Create a File object on the root of the directory // containing the class file File file = new File(classOutputFolder); try { // Convert File to a URL URL url = file.toURI().toURL(); // file:/classes/demo URL[] urls = new URL[]{url}; // Create a new class loader with the directory ClassLoader loader = new URLClassLoader(urls); // Load in the class; Class.childclass should be located in // the directory file:/class/demo/ Class thisClass = loader.loadClass("math.Calculator"); Class params[] = {}; Object paramsObj[] = {}; Object instance = thisClass.newInstance(); Method thisMethod = thisClass.getDeclaredMethod("testAdd", params); // run the testAdd() method on the instance: thisMethod.invoke(instance, paramsObj); } catch (MalformedURLException e) { } catch (ClassNotFoundException e) { } catch (Exception ex) { ex.printStackTrace(); } } public static Class getClass(String className, String classOutputFolder) { // Create a File object on the root of the directory // containing the class file File file = new File(classOutputFolder); try { // Convert File to a URL URL url = file.toURI().toURL(); // file:/classes/demo URL[] urls = new URL[]{url}; // Create a new class loader with the directory ClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader()); // Load in the class; Class.childclass should be located in // the directory file:/class/demo/ Class thisClass = loader.loadClass(className); // Class params[] = {}; // Object paramsObj[] = {}; // Object instance = thisClass.newInstance(); return thisClass; } catch (MalformedURLException e) { } catch (ClassNotFoundException e) { } catch (Exception ex) { ex.printStackTrace(); } return null; } public static void main(String[] args) throws Exception { //1.Construct an in-memory java source file from your dynamic code JavaFileObject file = getJavaFileObject(); Iterable files = Arrays.asList(file); //2.Compile your files by JavaCompiler compile(files, "/tmp"); //3.Load your class by URLClassLoader, then instantiate the instance, and call method by reflection runIt("/tmp"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy