zoukankan      html  css  js  c++  java
  • 动态编译和加载java代码

    package me.silentdoer.dynamicgeneration;
    
    import javax.tools.JavaCompiler;
    import javax.tools.SimpleJavaFileObject;
    import javax.tools.StandardJavaFileManager;
    import javax.tools.ToolProvider;
    import java.io.File;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.net.URI;
    import java.nio.charset.StandardCharsets;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    import java.util.Locale;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * if IDE is idea, change working dir to xxx/target/classes
     *
     * @author liqi.wang
     * @version 1.0.0
     * @since 2020/9/28 15:05
     */
    public class Entrance {
        /**
         * package's folder must exists
         */
        public static String inputCode = "package dynamic.generation.mock; public class UserFuck" +
                " { public static void test(){System.out.println("Hello444");}}";
    
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException
                , IllegalAccessException, InstantiationException, InvocationTargetException {
    
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            StandardJavaFileManager manager = compiler.getStandardFileManager(null, Locale.CHINA, StandardCharsets.UTF_8);
            // dynamic/generation is the based folder for generated code package
            File file = new File("dynamic/generation");
            if (file.exists() && file.isFile()) {
                throw new IllegalStateException("package folder is a file");
            } else if (!file.exists()) {
                boolean flag = file.mkdirs();
                if (!flag) {
                    throw new IllegalStateException("create package's folder failure.");
                }
            }
            // can cache value, and if exists .class, ignore
            String className = parseClassName(inputCode);
            StringSourceJavaObject sourceObject = new StringSourceJavaObject(className, Entrance.inputCode);
            List<StringSourceJavaObject> objects = Collections.singletonList(sourceObject);
            // define output dir
            List<String> options = Arrays.asList("-d", "./");
            JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, options, null, objects);
            Boolean compilerResult = task.call();
            if (compilerResult) {
                System.out.println("compile success");
                ClassLoader classLoader = Entrance.class.getClassLoader();
                // this throws ClassNotFoundException
                Class<?> userFuck = classLoader.loadClass(className);
                Method test = userFuck.getMethod("test");
                test.invoke(userFuck.newInstance());
            }
        }
    
        static String parseClassName(String inputCode) {
            Pattern packagePattern = Pattern.compile("package\s+(\S+);\s*");
            Matcher packageMatcher = packagePattern.matcher(inputCode);
            if (!packageMatcher.find()) {
                throw new IllegalArgumentException("input code is invalid.");
            }
            String packageName = packageMatcher.group(1);
            System.out.println("package: " + packageName);
            Pattern classSimpleNamePatter = Pattern.compile("public\s+class\s+(\w+)\s+\{");
            Matcher classSimpleNameMatcher = classSimpleNamePatter.matcher(inputCode);
            if (!classSimpleNameMatcher.find()) {
                throw new IllegalArgumentException("input code is invalid.");
            }
            String classSimpleName = classSimpleNameMatcher.group(1);
            System.out.println("className: " + classSimpleName);
            return packageName + "." + classSimpleName;
        }
    
        static class StringSourceJavaObject extends SimpleJavaFileObject {
    
            private final String sourceCode;
    
            public StringSourceJavaObject(String className, String sourceCode) {
                // DynamicCodeGen.UserFuck . to /
                super(URI.create("string:///" + className.replace(".", "/") + Kind.SOURCE.extension), Kind.SOURCE);
                this.sourceCode = sourceCode;
            }
    
            @Override
            public CharSequence getCharContent(boolean ignoreEncodingErrors) {
                return this.sourceCode;
            }
        }
    }
  • 相关阅读:
    [转]asp.net页面缓存技术
    UL和LI在div中的高度的IE6下兼容性
    jquery制作的横向图片滚动带横向滚动条TackerScroll
    电脑可以上网,但是qq登陆不上去?
    Introduction to discrete event system学习笔记4.6
    Introduction to Discrete event system学习笔记4.9
    Introduction to discrete event systemsstudy 4.5
    Symbolic synthesis of obserability requirements for diagnosability B.Bittner,M.Bozzano,A.Cimatti,and X.Olive笔记4.16
    Introduction to discrete event system学习笔记4.8pm
    Introduction to discrete event system学习笔记 4.8
  • 原文地址:https://www.cnblogs.com/silentdoer/p/13750458.html
Copyright © 2011-2022 走看看