This commit is contained in:
Looly 2022-05-09 18:47:02 +08:00
parent 935430099e
commit 435bd27346
4 changed files with 64 additions and 54 deletions

View File

@ -1,7 +1,10 @@
package cn.hutool.core.compiler;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.compress.ZipUtil;
import cn.hutool.core.io.resource.FileResource;
import cn.hutool.core.io.resource.Resource;
import javax.tools.JavaFileObject;
import java.io.File;
@ -17,26 +20,59 @@ import java.util.zip.ZipFile;
*/
public class JavaFileObjectUtil {
/**
* 获取指定资源下的所有待编译的java源码文件并以{@link JavaFileObject}形式返回
* <ul>
* <li>如果资源为目录则遍历目录找到目录中的.java或者.jar等文件加载之</li>
* <li>如果资源为.jar或.zip等解压读取其中的.java文件加载之</li>
* <li>其他情况直接读取资源流并加载之</li>
* </ul>
*
* @param resource 资源可以为目录文件或流
* @return 所有待编译的 {@link JavaFileObject}
*/
public static List<JavaFileObject> getJavaFileObjects(final Resource resource) {
final List<JavaFileObject> result = new ArrayList<>();
if (resource instanceof FileResource) {
final File file = ((FileResource) resource).getFile();
result.addAll(JavaFileObjectUtil.getJavaFileObjects(file));
} else {
result.add(new JavaSourceFileObject(resource.getName(), resource.getStream()));
}
return result;
}
/**
* 获取指定文件下的所有待编译的java文件并以{@link JavaFileObject}形式返回
* <ul>
* <li>如果文件为目录则遍历目录找到目录中的.java或者.jar等文件加载之</li>
* <li>如果文件为.jar或.zip等解压读取其中的.java文件加载之</li>
* </ul>
*
* @param file 文件或目录文件支持.java.jar和.zip文件
* @return 所有待编译的 {@link JavaFileObject}
*/
public static List<JavaFileObject> getJavaFileObjects(final File file) {
final List<JavaFileObject> result = new ArrayList<>();
final String fileName = file.getName();
if (isJavaFile(fileName)) {
result.add(new JavaSourceFileObject(file.toURI()));
} else if (isJarOrZipFile(fileName)) {
result.addAll(getJavaFileObjectByZipOrJarFile(file));
if (file.isDirectory()) {
FileUtil.walkFiles(file, (subFile) -> result.addAll(getJavaFileObjects(file)));
} else {
final String fileName = file.getName();
if (isJavaFile(fileName)) {
result.add(new JavaSourceFileObject(file.toURI()));
} else if (isJarOrZipFile(fileName)) {
result.addAll(getJavaFileObjectByZipOrJarFile(file));
}
}
return result;
}
/**
* 是否是jar zip 文件
* 是否是jar zip 文件<br>
* 通过扩展名判定
*
* @param fileName 文件名
* @return 是否是jar zip 文件
@ -46,7 +82,8 @@ public class JavaFileObjectUtil {
}
/**
* 是否是java文件
* 是否是java文件<br>
* 通过扩展名判定
*
* @param fileName 文件名
* @return 是否是.java文件

View File

@ -1,5 +1,6 @@
package cn.hutool.core.compiler;
import cn.hutool.core.classloader.ClassLoaderUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
@ -7,11 +8,9 @@ import cn.hutool.core.io.resource.FileResource;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.io.resource.StringResource;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.classloader.ClassLoaderUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.net.URLUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler.CompilationTask;
@ -22,11 +21,8 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Java 源码编译器
@ -230,40 +226,9 @@ public class JavaSourceCompiler {
final List<JavaFileObject> list = new ArrayList<>();
for (final Resource resource : this.sourceList) {
if (resource instanceof FileResource) {
final File file = ((FileResource) resource).getFile();
FileUtil.walkFiles(file, (subFile) -> list.addAll(JavaFileObjectUtil.getJavaFileObjects(file)));
} else {
list.add(new JavaSourceFileObject(resource.getName(), resource.getStream()));
}
list.addAll(JavaFileObjectUtil.getJavaFileObjects(resource));
}
return list;
}
/**
* 通过源码Map获得Java文件对象
*
* @param sourceCodeMap 源码Map
* @return Java文件对象集合
*/
private Collection<JavaFileObject> getJavaFileObjectByMap(final Map<String, String> sourceCodeMap) {
if (MapUtil.isNotEmpty(sourceCodeMap)) {
return sourceCodeMap.entrySet().stream()
.map(entry -> new JavaSourceFileObject(entry.getKey(), entry.getValue(), CharsetUtil.UTF_8))
.collect(Collectors.toList());
}
return Collections.emptySet();
}
/**
* 通过.java文件创建Java文件对象
*
* @param file .java文件
* @return Java文件对象
*/
private JavaFileObject getJavaFileObjectByJavaFile(final File file) {
return new JavaSourceFileObject(file.toURI());
}
}

View File

@ -2,8 +2,10 @@ package cn.hutool.core.compiler;
import cn.hutool.core.compress.ZipUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.reflect.ConstructorUtil;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
@ -16,6 +18,13 @@ import java.io.InputStream;
*/
public class JavaSourceCompilerTest {
@Test
@Ignore
public void compilerATest(){
final boolean compile = CompilerUtil.compile(FileUtil.file("test-compile/a/A.java").getAbsolutePath());
Assert.assertTrue(compile);
}
/**
* 测试编译Java源码
*/
@ -29,6 +38,7 @@ public class JavaSourceCompilerTest {
FileUtil.getInputStream("test-compile/a/A$1.class"),
FileUtil.getInputStream("test-compile/a/A$InnerClass.class")
});
Console.log(libFile.getAbsolutePath());
final ClassLoader classLoader = CompilerUtil.getCompiler(null)
.addSource(FileUtil.file("test-compile/b/B.java"))
.addSource("c.C", FileUtil.readUtf8String("test-compile/c/C.java"))

View File

@ -1,5 +1,6 @@
package a;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.ConsoleTable;
import cn.hutool.core.lang.caller.CallerUtil;
@ -10,15 +11,12 @@ public class A {
public A() {
new InnerClass() {{
int i = 0;
Class<?> caller = CallerUtil.getCaller(i);
final ConsoleTable t = new ConsoleTable();
t.addHeader("类名", "类加载器");
System.out.println("初始化 " + getClass() + " 的调用链为: ");
while (caller != null) {
t.addBody(caller.toString(), caller.getClassLoader().toString());
Console.log("初始化 " + getClass() + " 的调用链为: ");
Class<?> caller = CallerUtil.getCaller(i);
while (caller != null) {
Console.log("{} {}", caller, caller.getClassLoader());
caller = CallerUtil.getCaller(++i);
}
t.print();
}};
}
}