Java Dynamic - dynamic compile

Posted by dv90 on Fri, 13 Dec 2019 21:09:36 +0100

1. Dynamic compilation

  • Java 6.0 introduces compilation mechanism
  • Application scenarios of dynamic compilation:

    • It can make a browser to write java code, upload the server to compile and run the online evaluation system
    • The server dynamically loads some class files for compilation
  • There are two methods of dynamic compilation:

    • Call javac through Runtime to start a new process to operate (before 6.0, not real dynamic compilation)

      Runtime run = Runtime.getRuntime();

      Process process = run.exec("javac -cp d:/myjava/Helloworld.java")

    • Dynamic compilation through JavaCompiler
  • Dynamic compilation through JavaCompiler

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

    int result = compiler.run(null, null, null, "f:/HelloWorld.java");
    Parameters:
    in "standard" input; use System.in if null
    out "standard" output; use System.out if null
    err "standard" error; use System.err if null
    arguments arguments to pass to the tool

Chestnut:

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, "f:/HelloWorld.java");
System.out.println(result==0?"Compile successfully":"Compile failed");

2. Dynamically run compiled classes

  • Start a new process by running Runtime.getRuntime()
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, "f:/HelloWorld.java");
System.out.println(result==0?"Compile successfully":"Compile failed");
Runtime run = Runtime.getRuntime();
Process process = run.exec("java -cp f: HelloWorld");
        
BufferedReader w = new BufferedReader(new InputStreamReader(process.getInputStream()));
System.out.println(w.readLine());
  • Running compiled classes by reflection
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class DynamicCompile {

    public static void main(String[] args) throws IOException {

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int result = compiler.run(null, null, null, "f:/HelloWorld.java");
        System.out.println(result==0?"Compile successfully":"Compile failed");
    
        try {
            URL[] urls = new URL[]{new URL("file:/"+"f:/")};
            URLClassLoader loader = new URLClassLoader(urls);
            Class<?> c = loader.loadClass("HelloWorld");
            Method m = c.getMethod("main", String[].class);
            m.invoke(null, (Object)new String[]{});//Objects called by static methods without thanks
            //Reason for adding Object cast
            //Since the variable parameter is JDK5.0, m.invoke(null, new String[]{"23","34"}) is available;
            //The compiler will compile it into the format of m.invoke(null,"23","34"); and there will be parameter mismatch
            //Do this for parameters with arrays
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Topics: Java