JAVA动态编译

来源:互联网 发布:因windows system32 编辑:程序博客网 时间:2024/05/17 03:48

今天在弄游戏的GM模块,大部分gm命令很简单,只是单纯改变某些参数的值。
 
突然,想到一个问题,就是在线上运行服务器时,假如我要改变某个参数的值,有
 
没有办法呢?通过查找资料后,发现jdk竟然也提供了动态编译的工具。因此,我
 
们可以让java变成一个脚本语言。我发送一个类的代码到服务端,动态编译后,利
 
用反射来执行。代码很简单,我从网上找了一个例子简单改装一下




import java.io.IOException;  
import java.lang.reflect.Method;  
import java.net.URI;  
import java.net.URL;  
import java.net.URLClassLoader;  
import java.util.Arrays;  
import java.util.Scanner;  
  
import javax.tools.JavaCompiler;  
import javax.tools.JavaCompiler.CompilationTask;  
import javax.tools.JavaFileObject;  
import javax.tools.SimpleJavaFileObject;  
import javax.tools.ToolProvider;  
  
public class CompileTest {  
  
    public static final String CLASS_CONTENT = "public class HelloWorld{public static void run(){##;}}";  
  
    public static void main(String[] args) throws Exception {  
        Scanner scanner =new Scanner(System.in);  
        String code = scanner.nextLine();  
        code = CLASS_CONTENT.replace("##", code);  
          
        //获取编译器.注意,运行时需要jdk,单纯的jre没有编译器  
        JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();  
        JavaFileObject fileObject = new JavaStringObject("HelloWorld",  
                code);  
        //编译过程  
        CompilationTask task = javaCompiler.getTask(null, null, null,  
                Arrays.asList("-d", "./bin"), null, Arrays.asList(fileObject));  
        if (!task.call()) {  
            System.out.println("编译失败!");  
        } else {  
            System.out.println("编译成功!");  
  
            //成功以后,就利用发射来执行这个类了  
            URL[] urls = new URL[] { new URL("file:/" + "./bin/") };  
            URLClassLoader classLoader = new URLClassLoader(urls);  
            Class<?> clazz = classLoader.loadClass("HelloWorld");  
            Method method = clazz.getDeclaredMethod("run");  
            method.invoke(clazz.newInstance());  
        }  
  
    }  
  
    static class JavaStringObject extends SimpleJavaFileObject {  
        private String code;  
  
        public JavaStringObject(String name, String code) {  
            super(URI.create(name + ".java"), Kind.SOURCE);  
            this.code = code;  
        }  
  
        @Override  
        public CharSequence getCharContent(boolean ignoreEncodingErrors)  
                throws IOException {  
            return code;  
        }  
    }  







运行代码
输入一条java语句,例如:System.out.println("hello,美女!"); 
 
总结
利用java的这个小特性,我们可以做一些有益的事情,很多时候不需要为了更改某些参数而停服了。

0 0