`
15606915740
  • 浏览: 18484 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
文章分类
社区版块
存档分类
最新评论

动态解析java

阅读更多
import javax.tools.*;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;

public class SynamicCompiler  extends  ClassLoader  {

    public static void main(String[] args) throws Exception {
        String classPath = "D:/test/class" ;
        System.out.println( calculate("1.0+1.0",classPath));
        SynamicCompiler synamicCompiler = new SynamicCompiler();
        Class clz = synamicCompiler.findClass("Main");
         Method method = clz.getMethod("test");
         Object obj = clz.newInstance();
        method.invoke(obj);
    }

    protected Class<?> findClass(String name) {
        String myPath = "file:/D:/test/class/Main.class";
        System.out.println(myPath);
        byte[] cLassBytes = null;
        Path path = null;
        try {
            path = Paths.get(new URI(myPath));
            cLassBytes = Files.readAllBytes(path);
        } catch (IOException | URISyntaxException e) {
            e.printStackTrace();
        }
        Class clazz = defineClass(name, cLassBytes, 0, cLassBytes.length);
        return clazz;
    }

    private static double calculate(String expr,String classPath) throws  Exception {
        String className = "Main";
        String methodName = "test";
        String source = "public class " + className + " { public static void " + methodName + "() {System.out.println(\"Hello World!\")"
                + "; } }";
        System.out.println(source);
        boolean result = complie(source,className, classPath);
        System.out.println(result);
        return 0;
    }

    public static boolean complie(String source,String className,String classPath){
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        StringSourceJavaObject sourceObject = null;
        try {
            Iterable<String> options = Arrays.asList("-d", classPath);
            sourceObject = new SynamicCompiler.StringSourceJavaObject(className, source);
            Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(sourceObject);
            JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, fileObjects);
            boolean result = false;
            try{
                 result = task.call();
            }catch (Exception e) {
                System.out.println("============");
            }
            return result ;
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return false ;
    }

    private static class StringSourceJavaObject extends SimpleJavaFileObject {

        private String content = null;

        public StringSourceJavaObject(String name, String content) throws URISyntaxException {
            super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
            this.content = content;
        }

        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
            return content;
        }
    }
}



上面那个类可以实现动态编译java文件并将编译的class内容存在磁盘
MemoryJavaFileManager可以重定向class字节码的内容,可以直接在内存中获取到字节码内容,操作步骤和上面一样只是compiler.getTask(),的参数改成,compiler.getTask(null, memoryJavaFileManager, null, null, null, fileObjects);就可以现实内存直接获取字节码内容了。
final class MemoryJavaFileManager extends ForwardingJavaFileManager {

    /**
     * Java source file extension.
     */
    private final static String EXT = ".java";

    private Map<String, byte[]> classBytes;

    public MemoryJavaFileManager(JavaFileManager fileManager) {
        super(fileManager);
        classBytes = new HashMap<>();
    }

    public Map<String, byte[]> getClassBytes() {
        return classBytes;
    }

    public void close() throws IOException {
        classBytes = new HashMap<String, byte[]>();
    }

    public void flush() throws IOException {
    }

    /**
     * A file object that stores Java bytecode into the classBytes map.
     */
    private class ClassOutputBuffer extends SimpleJavaFileObject {
        private String name;

        ClassOutputBuffer(String name) {
            super(toURI(name), Kind.CLASS);
            this.name = name;
        }

        public OutputStream openOutputStream() {
            return new FilterOutputStream(new ByteArrayOutputStream()) {
                public void close() throws IOException {
                    out.close();
                    ByteArrayOutputStream bos = (ByteArrayOutputStream) out;
                    classBytes.put(name, bos.toByteArray());
                }
            };
        }
    }

    public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location,
                                               String className,
                                               JavaFileObject.Kind kind,
                                               FileObject sibling) throws IOException {
        if (kind == JavaFileObject.Kind.CLASS) {
            return new ClassOutputBuffer(className);
        } else {
            return super.getJavaFileForOutput(location, className, kind, sibling);
        }
    }

    static URI toURI(String name) {
        File file = new File(name);
        if (file.exists()) {
            return file.toURI();
        } else {
            try {
                final StringBuilder newUri = new StringBuilder();
                //mfm是uri的写法,这里的mfm是自己定义的,可以按照自己喜欢的定义
                newUri.append("mfm:///");
                newUri.append(name.replace('.', '/'));
                if (name.endsWith(EXT)) newUri.replace(newUri.length() - EXT.length(), newUri.length(), EXT);
                return URI.create(newUri.toString());
            } catch (Exception exp) {
                return URI.create("mfm:///com/sun/script/java/java_source");
            }
        }
    }

}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics