diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/ProxyCompiler.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/ProxyCompiler.java deleted file mode 100644 index beaee047..00000000 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/ProxyCompiler.java +++ /dev/null @@ -1,299 +0,0 @@ -/** - * Copyright (c) 2022 aoshiguchen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package fun.asgc.neutrino.core.aop.proxy; - -import fun.asgc.neutrino.core.base.GlobalConfig; -import fun.asgc.neutrino.core.util.FileUtil; -import fun.asgc.neutrino.core.util.SystemUtil; -import lombok.extern.slf4j.Slf4j; - -import javax.tools.*; -import java.io.*; -import java.net.URI; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.*; -import java.util.stream.Collectors; - -/** - * - * @author: aoshiguchen - * @date: 2022/6/24 - */ -@Slf4j -@Deprecated -public class ProxyCompiler { - /** - * 收集编译过程信息 - */ - private static DiagnosticCollector diagnostics = new DiagnosticCollector<>(); - - protected volatile List options = null; - protected volatile boolean isUnpack = false; - - - protected List getOptions() { - - - if (options != null) { - return options; - } - - synchronized (this) { - if (options != null) { - return options; - } - - List ret = new ArrayList<>(); - ret.add("-target"); - ret.add("1.8"); - - String cp = getClassPath(); - if (cp != null && cp.trim().length() != 0) { - ret.add("-classpath"); - ret.add(cp); - } - - options = ret; - return options; - } - } - - /** - * 兼容 tomcat 丢失 class path,否则无法编译 - */ - protected String getClassPath() { - if (!SystemUtil.isStartupFromJar()) { - URLClassLoader classLoader = getURLClassLoader(); - if (classLoader == null) { - return null; - } - - int index = 0; - boolean isWindows = SystemUtil.isWindows(); - StringBuilder ret = new StringBuilder(); - for (URL url : classLoader.getURLs()) { - if (index++ > 0) { - ret.append(File.pathSeparator); - } - - String path = url.getFile(); - - // 如果是 windows 系统,去除前缀字符 '/' - if (isWindows && path.startsWith("/")) { - path = path.substring(1); - } - - // 去除后缀字符 '/' - if (path.length() > 1 && (path.endsWith("/") || path.endsWith(File.separator))) { - path = path.substring(0, path.length() - 1); - } - ret.append(path); - } - - return ret.toString(); - } - List list = new ArrayList<>(); - File file = new File(GlobalConfig.getGeneratorCodeSavePath() + "BOOT-INF/lib/"); - if (file.exists()) { - File[] files = file.listFiles(); - for (File f : files) { - list.add(f.getAbsolutePath()); - } - } - list.add(GlobalConfig.getGeneratorCodeSavePath() + "BOOT-INF/classes/"); - if (SystemUtil.isStartupFromJar()) { - list.add(SystemUtil.getCurrentJarFilePath()); - } - return list.stream().collect(Collectors.joining(File.pathSeparator)); - } - - protected URLClassLoader getURLClassLoader() { - ClassLoader ret = Thread.currentThread().getContextClassLoader(); - if (ret == null) { - ret = ProxyCompiler.class.getClassLoader(); - } - return (ret instanceof URLClassLoader) ? (URLClassLoader)ret : null; - } - - public void compile(ProxyClass proxyClass) { - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - if (compiler == null) { - throw new RuntimeException("Can not get javax.tools.JavaCompiler, check whether \"tools.jar\" is in the environment variable CLASSPATH \n" + - "Visit https://jfinal.com/doc/4-8 for details \n"); - } - - System.out.println("=====> classpath:" + getOptions()); - DiagnosticCollector collector = new DiagnosticCollector<>(); - try (MyJavaFileManager javaFileManager = new MyJavaFileManager(compiler.getStandardFileManager(collector, null, null))) { - - MyJavaFileObject javaFileObject = new MyJavaFileObject(proxyClass.getName(), proxyClass.getSourceCode()); - Boolean result = compiler.getTask(null, javaFileManager, collector, getOptions(), null, Arrays.asList(javaFileObject)).call(); - outputCompileError(result, collector); - - Map ret = new HashMap<>(); - for (Map.Entry e : javaFileManager.fileObjects.entrySet()) { - ret.put(e.getKey(), e.getValue().getByteCode()); - } - - proxyClass.setByteCode(ret); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void compileToFile(ProxyClass proxyClass) { - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - if (compiler == null) { - throw new RuntimeException("Can not get javax.tools.JavaCompiler, check whether \"tools.jar\" is in the environment variable CLASSPATH \n" + - "Visit https://jfinal.com/doc/4-8 for details \n"); - } - unpack(); - - File file = FileUtil.save(GlobalConfig.getGeneratorCodeSavePath() + proxyClass.getPkg().replaceAll("\\.", "/"), proxyClass.getName() + ".java", proxyClass.getSourceCode()); - StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(diagnostics, null, null); - - Iterable iterable = standardFileManager.getJavaFileObjects(file); - // 创建一个编译任务 - JavaCompiler.CompilationTask task = compiler.getTask(null, standardFileManager, diagnostics, getOptions(), null, iterable); - //JavaCompiler.CompilationTask 实现了 Callable 接口 - Boolean result = task.call(); - printLog(result, file); - } - - private synchronized void unpack() { - if (!SystemUtil.isStartupFromJar()) { - return; - } - if (isUnpack) { - return; - } - isUnpack = true; - try { - File file1 = new File(GlobalConfig.getGeneratorCodeSavePath() + "BOOT-INF/lib/"); - File file2 = new File(GlobalConfig.getGeneratorCodeSavePath() + "BOOT-INF/classes/"); - if (file1.exists() && file2.exists()) { - return; - } - log.info("解压jar:{} 到:{}", SystemUtil.getCurrentJarFilePath(), GlobalConfig.getGeneratorCodeSavePath()); - FileUtil.unzipJar(GlobalConfig.getGeneratorCodeSavePath(), SystemUtil.getCurrentJarFilePath()); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void printLog(Boolean result, File ...files){ - if (!result) { - StringJoiner rs = new StringJoiner(System.getProperty("line.separator")); - for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { - rs.add(String.format("%s:%s[line %d column %d]-->%s%n", diagnostic.getKind(), diagnostic.getSource(), diagnostic.getLineNumber(), - diagnostic.getColumnNumber(), - diagnostic.getMessage(null))); - } - log.error("编译失败,原因:{}", rs.toString()); - } else { - StringBuilder sb = new StringBuilder(); - Arrays.stream(files).forEach(file -> { - sb.append(file.getName()); - sb.append(";"); - }); - } - } - - protected void outputCompileError(Boolean result, DiagnosticCollector collector) { - if (! result) { - collector.getDiagnostics().forEach(item -> log.error(item.toString())); - } - } - - public ProxyCompiler setCompileOptions(List options) { - Objects.requireNonNull(options, "options can not be null"); - this.options = options; - return this; - } - - public ProxyCompiler addCompileOption(String option) { - Objects.requireNonNull(option, "option can not be null"); - options.add(option); - return this; - } - - public static class MyJavaFileObject extends SimpleJavaFileObject { - - private String source; - private ByteArrayOutputStream outPutStream; - - public MyJavaFileObject(String name, String source) { - super(URI.create("String:///" + name + JavaFileObject.Kind.SOURCE.extension), JavaFileObject.Kind.SOURCE); - this.source = source; - } - - public MyJavaFileObject(String name, JavaFileObject.Kind kind) { - super(URI.create("String:///" + name + kind.extension), kind); - source = null; - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - if (source == null) { - throw new IllegalStateException("source field can not be null"); - } - return source; - } - - @Override - public OutputStream openOutputStream() throws IOException { - outPutStream = new ByteArrayOutputStream(); - return outPutStream; - } - - public byte[] getByteCode() { - return outPutStream.toByteArray(); - } - } - - public static class MyJavaFileManager extends ForwardingJavaFileManager { - - public Map fileObjects = new HashMap<>(); - - public MyJavaFileManager(JavaFileManager fileManager) { - super(fileManager); - } - - @Override - public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, String qualifiedClassName, JavaFileObject.Kind kind, FileObject sibling) throws IOException { - MyJavaFileObject javaFileObject = new MyJavaFileObject(qualifiedClassName, kind); - fileObjects.put(qualifiedClassName, javaFileObject); - return javaFileObject; - } - - // 是否在编译时依赖另一个类的情况下用到本方法 ? - @Override - public JavaFileObject getJavaFileForInput(JavaFileManager.Location location, String className, JavaFileObject.Kind kind) throws IOException { - JavaFileObject javaFileObject = fileObjects.get(className); - if (javaFileObject == null) { - javaFileObject = super.getJavaFileForInput(location, className, kind); - } - return javaFileObject; - } - } -}