From 1ac2509f121414b15e4b083432a2bf57629dd2fe Mon Sep 17 00:00:00 2001 From: yuan <1363654894@qq.com> Date: Sun, 1 Sep 2024 15:50:13 +0800 Subject: [PATCH] =?UTF-8?q?feat():=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/muyu/compile/OSSFileCompile.java | 14 +- .../main/java/com/muyu/load/OSSFileLoad.java | 65 +++++-- .../main/java/com/muyu/util/JavaCodeScan.java | 169 ++++++++++++++++++ .../com/muyu/util/SourceCodeCompiler.java | 72 ++++++++ 4 files changed, 300 insertions(+), 20 deletions(-) create mode 100644 cloud-rule-engine/src/main/java/com/muyu/util/JavaCodeScan.java create mode 100644 cloud-rule-engine/src/main/java/com/muyu/util/SourceCodeCompiler.java diff --git a/cloud-rule-engine/src/main/java/com/muyu/compile/OSSFileCompile.java b/cloud-rule-engine/src/main/java/com/muyu/compile/OSSFileCompile.java index 48bd551..6c50fa1 100644 --- a/cloud-rule-engine/src/main/java/com/muyu/compile/OSSFileCompile.java +++ b/cloud-rule-engine/src/main/java/com/muyu/compile/OSSFileCompile.java @@ -2,10 +2,13 @@ package com.muyu.compile; import com.muyu.common.core.domain.Result; +import org.apache.catalina.startup.EngineConfig; import javax.tools.*; import java.io.File; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -40,22 +43,17 @@ public class OSSFileCompile{ public static Result compile(String source,String extLib){ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - // 设置编译选项,这里我们将输出目录设置为源文件的目录 - String outputDir = new File(source).getParent(); - String[] options = new String[]{"-d", outputDir}; - // 执行编译任务 - int result = compiler.run(null, null, null, Arrays.toString(options), source); + int result = compiler.run(null, null, null, source); // 检查编译结果 if (result == 0) { System.out.println("编译成功,生成的.class文件位于源代码同目录"); - Result.success("编译成功,生成的.class文件位于源代码同目录"); + return Result.success("编译成功,生成的.class文件位于源代码同目录"); } else { System.out.println("编译失败"); - Result.error("编译失败"); + return Result.error("编译失败"); } - return Result.warn(); } } diff --git a/cloud-rule-engine/src/main/java/com/muyu/load/OSSFileLoad.java b/cloud-rule-engine/src/main/java/com/muyu/load/OSSFileLoad.java index 5523ac6..434ab24 100644 --- a/cloud-rule-engine/src/main/java/com/muyu/load/OSSFileLoad.java +++ b/cloud-rule-engine/src/main/java/com/muyu/load/OSSFileLoad.java @@ -6,11 +6,9 @@ import com.aliyun.oss.model.OSSObject; import com.aliyun.oss.model.ObjectMetadata; import com.muyu.common.core.domain.Result; import com.muyu.compile.OSSFileCompile; +import com.muyu.util.SourceCodeCompiler; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.util.Map; /** @@ -51,6 +49,57 @@ public class OSSFileLoad { String localPath = "home/"+fileName; ObjectMetadata object = ossClient.getObject(new GetObjectRequest(bucketName, filePath + fileName), new File(localPath)); System.out.println(object); + + ossClient.shutdown(); + + try { + // 从OSS下载文件 + InputStream inputStream = ossClient.getObject(bucketName, filePath+fileName).getObjectContent(); + File downloadFile = new File(localPath); + FileOutputStream outputStream = new FileOutputStream(downloadFile); + + byte[] buffer = new byte[1024]; + int len; + while ((len = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, len); + } + outputStream.close(); + inputStream.close(); + + System.out.println("存放路径:" + localPath); + } catch (Exception e) { + e.printStackTrace(); + } finally { + // 关闭OSSClient + if (ossClient != null) { + ossClient.shutdown(); + } + } + + //对路径里的.java文件进行编译 + SourceCodeCompiler.javaCompilerPath("/home"); + System.out.println("第一步"); + File outputDir = new File("/home"); // 或者是你指定的其他输出目录 + System.out.println("第一步"); + File[] classFiles = outputDir.listFiles(); // 获取输出目录中的所有文件 + System.out.println("第三步"); + if (classFiles != null) { + for (File classFile : classFiles) { + if (classFile.getName().endsWith(".class")) { + // 这里可以处理每个.class文件,例如读取、复制或移动 + System.out.println("找到class文件 " + classFile.getName()); + } + } + //把.class文件存入oss中 + }else { + System.out.println("没有找到文件"); + } + + return Result.success(source); + } + +} + // OSSObject ossObject = ossClient.getObject(bucketName, fileName); // BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); // while(true){ @@ -61,12 +110,4 @@ public class OSSFileLoad { // System.out.println(source); // System.out.println("读取成功"); // reader.close(); - ossClient.shutdown(); - // Map compile = OSSFileCompile.compile(fileName, source, "target/"); - Result compile = OSSFileCompile.compile(localPath, null); - System.out.println(compile.getData()); - return Result.success(source); - } - -} diff --git a/cloud-rule-engine/src/main/java/com/muyu/util/JavaCodeScan.java b/cloud-rule-engine/src/main/java/com/muyu/util/JavaCodeScan.java new file mode 100644 index 0000000..ba995ae --- /dev/null +++ b/cloud-rule-engine/src/main/java/com/muyu/util/JavaCodeScan.java @@ -0,0 +1,169 @@ +package com.muyu.util; + +import lombok.extern.log4j.Log4j2; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName JavaCodeScan + * @Description 描述 + * @Author YiBo.Liu + * @Date 2024/8/23 10:36 + */ +@Log4j2 +public class JavaCodeScan extends ClassLoader{ + + + public static final String JAVA_SOURCE_SUF = ".java"; + public static final String JAVA_BINARY_SUF = ".class"; + + private static final JavaCodeScan loader = new JavaCodeScan(); + + /** + * + * @param filePath 文件路径 + * @param suf 扫描后缀 + * @return + */ + public static File[] filterFileBySuf(String filePath,String suf){ + //创建需要扫描的文件夹 + File file = new File(filePath); + //列出所有的筛选suf结尾的文件集 + //file.listFiles(筛选) + File[] childFiles = file.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + if(name.indexOf(suf) <= -1){ + return false; + }else { + log.info("扫描到{}文件->{}",suf,name); + return true; + } + + } + }); + return childFiles; + } + + /** + * @param pack 类所在的包名 com.muyu.bean. 后面需要带个点 + * @param location 包所在路径 + * @return + */ + public static Map> loadClassByLocation(String pack, String location) { + //列出所有的class文件 + List classFiles = JavaCodeScan.getClassFile(location); + HashMap> map = new HashMap<>(); + classFiles.forEach(file -> { + String name = file.getName().substring(0, file.getName().lastIndexOf(JAVA_BINARY_SUF)); + Class c = loadClassByNameAndLocation(name, pack + ".", new File(location)); + map.put(name, c); + }); + return map; + } + + + /** + *自定义路径获取类的class对象 + * @param name + * @param pack + * @param locationFile + * @return + */ + private static Class loadClassByNameAndLocation(String name, String pack, File locationFile) { + //将class文件的数据读入到byte数组中 + byte[] datas = loader.loadClassData(name, locationFile); + //通过byte数组加载Class对象 + Class aClass = loader.defineClass(pack + name, datas, 0, datas.length); + log.info("成功加载规则引擎 -- {}", aClass.getName()); + return aClass; + } + + /** + * 将文件转换成字节数组 + * + * @param name 文件名称 + * @param locationFile 文件 + * @return + */ + public byte[] loadClassData(String name, File locationFile) { + byte[] byteArray = null; + try {FileInputStream fis = new FileInputStream(locationFile + "/" + name + JAVA_BINARY_SUF); + // 创建ByteArrayOutputStream对象 + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // 创建一个缓冲区 + byte[] buffer = new byte[1024]; + int length; + // 读取文件内容并写入缓冲区 + while ((length = fis.read(buffer)) != -1) { + bos.write(buffer, 0, length); + } + // 将缓冲区中的内容转换为byte数组 + byteArray = bos.toByteArray(); + } catch (IOException e) { + log.error("[【{}】文件转换成字节数组错误]:{}", name, e.getMessage(), e); + throw new RuntimeException(e); + } + return byteArray; + } + + + /** + * 判断java文件类型 + * @param file 文件 + * @return 布尔类型的值 + */ + public static Boolean isFileType(File file) { + return file.getName().endsWith(JAVA_SOURCE_SUF); + } + + /** + * 判断是否为class文件类型 + * @param file + * @return + */ + public static Boolean isClassFileType(File file){ + return file.getName().endsWith(JAVA_BINARY_SUF); + } + + /** + * 通过文件路径获取该文件夹下的所有java类型文件 + * @param folderPath 文件夹路径 + * @return java文件 + */ + public static List getJavaFiles(String folderPath) { + File folder = new File(folderPath); + if (!folder.exists()){ + folder.mkdirs(); + } + File[] files = folder.listFiles(); + return Arrays.stream(isFilesExist(files)).filter(JavaCodeScan::isFileType).toList(); + } + + + /** + * 通过路劲获取所有的.class文件 + * @param location + * @return + */ + private static List getClassFile(String location) { + File file = new File(location); + if(!file.exists()){ + file.mkdirs(); + } + File[] files = file.listFiles(); + return Arrays.stream(isFilesExist(files)).filter(JavaCodeScan::isClassFileType).toList(); + } + + private static File[] isFilesExist(File[] files) { + if(files == null || files.length == 0){ + throw new RuntimeException("该文件夹下没有文件"); + } + return files; + } +} diff --git a/cloud-rule-engine/src/main/java/com/muyu/util/SourceCodeCompiler.java b/cloud-rule-engine/src/main/java/com/muyu/util/SourceCodeCompiler.java new file mode 100644 index 0000000..4c2e4a8 --- /dev/null +++ b/cloud-rule-engine/src/main/java/com/muyu/util/SourceCodeCompiler.java @@ -0,0 +1,72 @@ +package com.muyu.util; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import java.io.File; +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName SourceCodeCompiler + * @Description 描述 + * @Author YiBo.Liu + * @Date 2024/8/23 10:35 + */ +public class SourceCodeCompiler { + + private static final Logger log = LogManager.getLogger(SourceCodeCompiler.class.getName()); + + /** + * 获取系统java编译器 + */ + private static JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + /** + * 获取java文件管理器 + */ + private static StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + + + /** + * 输入编译的文件夹路径 + * @param path 文件夹路径 + */ + public static void javaCompilerPath(String path){ + List files = JavaCodeScan.getJavaFiles(path); + File[] array = files.toArray(new File[files.size()]); + javaCompiler(array); + + + } + + + public static void javaCompilerFile(String... filePath){ + int filePathLength = filePath.length; + File[] files = new File[filePathLength]; + + for (int i = 0; i < filePathLength; i++) { + files[i] = new File(filePath[i]); + } + javaCompiler(files); + } + + + /** + *可以同时编译多个java源代码 + * @param file + */ + public static void javaCompiler(File...file){ + //通过源文件获取到想要编译的java类源代码迭代器,包括所有的内部类,其中每一个类都是一个JavaFileObjects,也被称为一个汇编单元 + Iterable javaFileObjects = fileManager.getJavaFileObjects(file); + //生成编译任务 + JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, Arrays.asList("-d","home"), null, javaFileObjects); + //执行编译任务 + task.call(); + } + +}