欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java内存动态编译执行,java动态编译,一般的java的动态编译

来源: javaer 分享于  点击 34287 次 点评:274

java内存动态编译执行,java动态编译,一般的java的动态编译


一般的java的动态编译是需要先生成java文件,然后编译成class,最后用classloader加载进来生成最终的实例的。本例程则不需要生成任何文件,一切在内存中进行。

[Java]代码

package cn.outofmemory.dynamic;public class DynaCompTest {    public static void main(String[] args) throws Exception {        String fullName = "DynaClass";        StringBuilder src = new StringBuilder();        src.append("public class DynaClass {\n");        src.append("    public String toString() {\n");        src.append("        return \"Hello, I am \" + ");        src.append("this.getClass().getSimpleName();\n");        src.append("    }\n");        src.append("}\n");        System.out.println(src);        DynamicEngine de = DynamicEngine.getInstance();        Object instance =  de.javaCodeToObject(fullName,src.toString());        System.out.println(instance);    }}

[Java]代码

package cn.outofmemory.dynamic;import javax.tools.*;import java.util.ArrayList;import java.util.List;import java.util.Arrays;import java.net.URL;import java.net.URLClassLoader;import java.io.File;public class DynamicEngine {    private static DynamicEngine ourInstance = new DynamicEngine();    public static DynamicEngine getInstance() {        return ourInstance;    }    private URLClassLoader parentClassLoader;    private String classpath;    private DynamicEngine() {        this.parentClassLoader = (URLClassLoader) this.getClass().getClassLoader();        this.buildClassPath();    }    private void buildClassPath() {        this.classpath = null;        StringBuilder sb = new StringBuilder();        for (URL url : this.parentClassLoader.getURLs()) {            String p = url.getFile();            sb.append(p).append(File.pathSeparator);        }        this.classpath = sb.toString();    }    public Object javaCodeToObject(String fullClassName, String javaCode) throws IllegalAccessException, InstantiationException {        long start = System.currentTimeMillis();        Object instance = null;        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();        ClassFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(diagnostics, null, null));        List<JavaFileObject> jfiles = new ArrayList<JavaFileObject>();        jfiles.add(new CharSequenceJavaFileObject(fullClassName, javaCode));        List<String> options = new ArrayList<String>();        options.add("-encoding");        options.add("UTF-8");        options.add("-classpath");        options.add(this.classpath);        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, jfiles);        boolean success = task.call();        if (success) {            JavaClassObject jco = fileManager.getJavaClassObject();            DynamicClassLoader dynamicClassLoader = new DynamicClassLoader(this.parentClassLoader);            Class clazz = dynamicClassLoader.loadClass(fullClassName,jco);            instance = clazz.newInstance();        } else {            String error = "";            for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {                error = error + compilePrint(diagnostic);            }        }        long end = System.currentTimeMillis();        System.out.println("javaCodeToObject use:"+(end-start)+"ms");        return instance;    }    private String compilePrint(Diagnostic diagnostic) {        System.out.println("Code:" + diagnostic.getCode());        System.out.println("Kind:" + diagnostic.getKind());        System.out.println("Position:" + diagnostic.getPosition());        System.out.println("Start Position:" + diagnostic.getStartPosition());        System.out.println("End Position:" + diagnostic.getEndPosition());        System.out.println("Source:" + diagnostic.getSource());        System.out.println("Message:" + diagnostic.getMessage(null));        System.out.println("LineNumber:" + diagnostic.getLineNumber());        System.out.println("ColumnNumber:" + diagnostic.getColumnNumber());        StringBuffer res = new StringBuffer();        res.append("Code:[" + diagnostic.getCode() + "]\n");        res.append("Kind:[" + diagnostic.getKind() + "]\n");        res.append("Position:[" + diagnostic.getPosition() + "]\n");        res.append("Start Position:[" + diagnostic.getStartPosition() + "]\n");        res.append("End Position:[" + diagnostic.getEndPosition() + "]\n");        res.append("Source:[" + diagnostic.getSource() + "]\n");        res.append("Message:[" + diagnostic.getMessage(null) + "]\n");        res.append("LineNumber:[" + diagnostic.getLineNumber() + "]\n");        res.append("ColumnNumber:[" + diagnostic.getColumnNumber() + "]\n");        return res.toString();    }}

[Java]代码

package cn.outofmemory.dynamic;import javax.tools.JavaFileObject;import javax.tools.SimpleJavaFileObject;import java.net.URI;public class CharSequenceJavaFileObject extends SimpleJavaFileObject {    private CharSequence content;    public CharSequenceJavaFileObject(String className,                                      CharSequence content) {        super(URI.create("string:///" + className.replace('.', '/')                + JavaFileObject.Kind.SOURCE.extension), JavaFileObject.Kind.SOURCE);        this.content = content;    }    @Override    public CharSequence getCharContent(            boolean ignoreEncodingErrors) {        return content;    }}

[Java]代码

package cn.outofmemory.dynamic;import javax.tools.*;import java.io.IOException;import java.security.SecureClassLoader;public class ClassFileManager extends        ForwardingJavaFileManager {    public JavaClassObject getJavaClassObject() {        return jclassObject;    }    private JavaClassObject jclassObject;    public ClassFileManager(StandardJavaFileManager        standardManager) {        super(standardManager);    }    @Override    public JavaFileObject getJavaFileForOutput(Location location,        String className, JavaFileObject.Kind kind, FileObject sibling)            throws IOException {            jclassObject = new JavaClassObject(className, kind);        return jclassObject;    }}

[Java]代码

package cn.outofmemory.dynamic;import javax.tools.JavaFileObject;import javax.tools.SimpleJavaFileObject;import java.io.IOException;import java.io.OutputStream;import java.io.ByteArrayOutputStream;import java.net.URI;public class JavaClassObject extends SimpleJavaFileObject {    protected final ByteArrayOutputStream bos =        new ByteArrayOutputStream();    public JavaClassObject(String name, JavaFileObject.Kind kind) {        super(URI.create("string:///" + name.replace('.', '/')            + kind.extension), kind);    }    public byte[] getBytes() {        return bos.toByteArray();    }    @Override    public OutputStream openOutputStream() throws IOException {        return bos;    }}

[Java]代码

package cn.outofmemory.dynamic;import java.net.URLClassLoader;import java.net.URL;public class DynamicClassLoader extends URLClassLoader {    public DynamicClassLoader(ClassLoader parent) {        super(new URL[0], parent);    }    public Class findClassByClassName(String className) throws ClassNotFoundException {        return this.findClass(className);    }    public Class loadClass(String fullName, JavaClassObject jco) {        byte[] classData = jco.getBytes();        return this.defineClass(fullName, classData, 0, classData.length);    }}
相关栏目:

用户点评