Dynamic execution of a simple code, using the generation of java files, call javac compilation, reflection of the way of execution.
Use the I / O stream (or what you might say is to use reflection to get the program results to parse) to parse *. Java files.
You can then use runtime to call the java compile command under Dos to compile the class file.
Then use the combination of classloader and reflection to execute the generated class file.
package loadjarclass; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import org.junit.Test; public class LoadJarClassTest { @Test public void testLoadClass() throws Exception{ /*Dynamically load the specified class*/ File file=new File("D:/test");//Classpath (package file level up) URL url=file.toURI().toURL(); ClassLoader loader=new URLClassLoader(new URL[]{url});//Create class loader //import com.sun.org.apache.bcel.internal.util.ClassLoader; //ClassLoader classLoader = new ClassLoader(new String [] {""}); / / classpath Class<?> cls=loader.loadClass("loadjarclass.TestTest");//Load the specified class. Be sure to bring the package name of the class Object obj=cls.newInstance();//Initializing an instance Method method=cls.getMethod("printString",String.class,String.class);//Method name and corresponding parameter type Object o=method.invoke(obj,"chen","leixing");//Call the method on the top System.out.println(String.valueOf(o));//Output "CHENLEI Xing" /*Dynamically load the specified jar package to call a method of one of its classes*/ file=new File("D:/test/commons-lang3.jar");//Path of jar package url=file.toURI().toURL(); loader=new URLClassLoader(new URL[]{url});//Create class loader cls=loader.loadClass("org.apache.commons.lang3.StringUtils");//Load the specified class. Be sure to bring the package name of the class method=cls.getMethod("center",String.class,int.class,String.class);//Method name and corresponding parameter types o=method.invoke(null,"chen",Integer.valueOf(10),"0");//Call the upper method (static method, the first parameter can be null) System.out.println(String.valueOf(o));//Output "000chen000","chen" string with 3 "0" strings on both sides } }
Use com.sun.tools.javac.Main to compile the Java source code. The script is as follows. I did some research, wrote a demo, and recorded it, which is also convenient for later people to learn.
$ bin/hadoop com.sun.tools.javac.Main WordCount.java $ jar cf wc.jar WordCount*.class
com.sun.tools.javac.Main
This class is located in ${JAVA_HOME}/lib/tools.jar and needs to be added to the classpath or introduced directly into the IDE. This is the same as calling javac commands directly. The following is demo. Use the compile method in the Main class to compile a Person.java source file, and then load the bytecode for execution.
1. Prepare the java source code to be compiled.
The following code is a simple PersonAction, which implements an Action interface Action. It is not necessary to implement the interface, but it is convenient to instantiate a specific type object later.
import inf.Action; public class PersonAction implements Action{ @Override public void say(String msg){ System.out.println("Person say a message: "+msg); } } package inf; public interface Action { public void say(String msg); }
2. Write the executed code, which is used to compile PersonAction.java. After the compilation is successful, load the bytecode to JRE for execution
package demo; import inf.Action; import java.io.*; import java.lang.reflect.Method; /** * Created by rns on 17-1-7. */ public class DynamicCompiler { public static void main(String[] args) throws IOException { //The folder path where the source code to be compiled is placed String basedir = "/home/rns/Desktop/test/"; //Class name to be compiled, excluding. java String classname = "PersonAction"; //The path to execute the code. The following path is my idea's compiled output path String executedir = "/home/rns/IdeaProjects_community/" +"DynamicCompileAndRun/out/production/DynamicCompileAndRun/"; //Create compiler com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main(); //Set the parameters of the compile command, just like the parameters after the javac command String[] params = new String[] { "-d", basedir,basedir+classname+".java", "-verbose" }; int status = javac.compile(params); //Success when compile return value is 0 if(status == 0) System.out.println("compiled successfully!"); else System.out.println("errors occurs"); //Deploy compiled class to execution directory copyTo(basedir+classname+".class",executedir+classname+".class"); //Load the class bytecode and instantiate it, then call the corresponding method invoke(classname,"say",new Class[]{String.class},new String[]{"Hello"}); } /** * Instantiate and call the appropriate method * @param classname Class name * @param methodname Method name * @param paramType Method parameter type * @param paramValues Method parameter value */ public static void invoke(String classname, String methodname, Class[] paramType, Object[] paramValues){ try { Class cls = Class.forName(classname); // Mode 1: do not convert to specific types, // Create a Method instance with reflection, and then implement Method call Method method = cls.getMethod(methodname, paramType); method.invoke(cls.newInstance(),paramValues); // Mode 2: conversion to specific type (corresponding interface needs to be designed), // After reflection instantiation, cast to interface type, and then make method call Action person = (Action) cls.newInstance(); person.say(paramValues[0].toString()); } catch (Exception e) { e.printStackTrace(); } } /** * Copy files to specified directory * @param from source file * @param to Destination file * @throws IOException */ public static void copyTo(String from,String to) throws IOException { FileInputStream fi = new FileInputStream(from); FileOutputStream fo = new FileOutputStream(to); File df = new File(to); if(!df.exists()) df.createNewFile(); for(int read = fi.read(); read !=-1; read=fi.read()){ fo.write(read); } fo.close(); fi.close(); } }
3. Implementation results
/usr/jdk1.8.0_111/bin/java ... compiled successfully! Person say a message: Hello Person say a message: Hello Process finished with exit code 0