zoukankan      html  css  js  c++  java
  • JAVA动态编译辅助类

    一、场景

    平时我们学学用到在JVM运行时,动态编译.java的源代码情况,比如作为灵活的配置文件。这时候就要用到动态编译,参考下列。

    二、类内容

    1、引入依赖:

    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>

    2、编写基本类,让它继承 SimpleJavaFileObject 类。

    package com.songxingzhu.utils.compile;
    
    import javax.tools.SimpleJavaFileObject;
    import java.net.URI;
    
    public class JavaSourceFromCodeString extends SimpleJavaFileObject {
        final String code;
    
        public JavaSourceFromCodeString(String name, String code) {
            super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
            this.code = code;
        }
    
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return this.code;
        }
    }

    2、编写工具类

    package com.songxingzhu.utils.context;
    
    import java.io.File;
    
    public class AppContext {
        public static String baseDirectory() {
            try {
                String path = ClassLoader.getSystemResource("").getPath();
                if (path==null||"".equal(path))
                    return getProjectPath();
                return path;
            } catch (Exception ignored) {
            }
            return getProjectPath();
        }
    
        private static String getProjectPath() {
            java.net.URL url = AppContext.class.getProtectionDomain().getCodeSource()
                    .getLocation();
            String filePath = null;
            try {
                filePath = java.net.URLDecoder.decode(url.getPath(), "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (filePath.endsWith(".jar"))
                filePath = filePath.substring(0, filePath.lastIndexOf(File.separatorChar) + 1);
            java.io.File file = new java.io.File(filePath);
            filePath = file.getAbsolutePath();
            return filePath;
        }
    }
    package com.songxingzhu.utils.compile;
    
    import org.apache.commons.io.FileUtils;
    import com.songxingzhu.utils.context.AppContext;
    
    import javax.tools.JavaCompiler;
    import javax.tools.JavaFileManager;
    import javax.tools.JavaFileObject;
    import javax.tools.ToolProvider;
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.net.URLClassLoader;
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class ClassBuilder {
    
        public static Class<?> buildClass(String fullClassName, String codeFilePath) throws IOException, ClassNotFoundException {
    
            return buildClass(fullClassName, codeFilePath, "UTF-8", AppContext.baseDirectory());
        }
    
        public static Class<?> buildClass(String fullClassName, String codeFilePath, String charsetName, String buildOutput) throws IOException, ClassNotFoundException {
            try {
                String code = FileUtils.readFileToString(FileUtils.getFile(codeFilePath), charsetName);
                JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
                JavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
                List<JavaFileObject> files = new ArrayList<>();
                files.add(new JavaSourceFromCodeString(fullClassName, code));
                List<String> options = new ArrayList<>();
                options.add("-classpath");
                StringBuilder sb = new StringBuilder();
                URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
                for (URL url : urlClassLoader.getURLs()) {
                    sb.append(url.getFile()).append(File.pathSeparator);
                }
                options.add(sb.toString());
                options.add("-d");
                options.add(buildOutput);
                // execute the compiler
                boolean isok = compiler.getTask(null, fileManager, null, options, null, files).call();
                if (isok) {
                    File root = new File(buildOutput);
                    if (!root.exists()) root.mkdirs();
                    URL[] urls = new URL[]{root.toURI().toURL()};
                    ClassLoader classLoader = ClassBuilder.class.getClassLoader();
                    Class<?> clazz = Class.forName(fullClassName, true, classLoader);
                    return clazz;
                }
                return null;
            } catch (Exception ex) {
                throw ex;
            }
        }
    }
  • 相关阅读:
    LoaRunner性能测试系统学习教程:日志文件分析(8)
    LoaRunner性能测试系统学习教程:MPM相关参数(7)
    LoaRunner性能测试系统学习教程:MPM调优(6)
    响应器
    分页器
    权限组件、频率组件
    drf视图组件、认证组件
    drf序列化组件
    RESTful
    IO操作、PIL使用、Django的admin操作
  • 原文地址:https://www.cnblogs.com/songxingzhu/p/9002352.html
Copyright © 2011-2022 走看看