diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java index e6696879..5baa68fe 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java @@ -69,7 +69,7 @@ public class AsgcCompiler { this.standardJavaFileManager = javaCompiler.getStandardFileManager(collector, null, null); this.isSaveClassFile = false; this.generatorCodeSavePath = GlobalConfig.getGeneratorCodeSavePath(); - this.dynamicClassLoader = new DynamicClassLoader(classLoader); + this.dynamicClassLoader = new DynamicClassLoader(this, classLoader); addOption("-Xlint:unchecked"); addOption("-implicit:class"); @@ -193,7 +193,7 @@ public class AsgcCompiler { return (ret instanceof URLClassLoader) ? (URLClassLoader)ret : null; } - private List getClasspathList() { + public List getClasspathList() { List classpathList = new ArrayList<>(); List defaultClasspathList = getDefaultClasspathList(); List customClasspathList = this.classpathList; diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/DynamicClassLoader.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/DynamicClassLoader.java index 1810ca5a..5abce963 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/DynamicClassLoader.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/DynamicClassLoader.java @@ -21,8 +21,11 @@ */ package fun.asgc.neutrino.core.aop.compiler; -import java.util.HashMap; -import java.util.Map; +import fun.asgc.neutrino.core.util.ClassUtil; +import fun.asgc.neutrino.core.util.CollectionUtil; + +import java.net.URL; +import java.util.*; /** * @@ -31,11 +34,17 @@ import java.util.Map; */ public class DynamicClassLoader extends ClassLoader { private final Map byteCodes = new HashMap<>(); + private AsgcCompiler compiler; public DynamicClassLoader(ClassLoader classLoader) { super(classLoader); } + public DynamicClassLoader(AsgcCompiler compiler, ClassLoader classLoader) { + super(classLoader); + this.compiler = compiler; + } + public void registerCompiledSource(MemoryByteCode byteCode) { byteCodes.put(byteCode.getClassName(), byteCode); } @@ -43,11 +52,47 @@ public class DynamicClassLoader extends ClassLoader { @Override protected Class findClass(String name) throws ClassNotFoundException { MemoryByteCode byteCode = byteCodes.get(name); - if (null == byteCode) { - return super.findClass(name); + if (null != byteCode) { + return super.defineClass(name, byteCode.getByteCode(), 0, byteCode.getByteCode().length); } + Class ret = doFindClass(name); + if (null != ret) { + return ret; + } + return super.findClass(name); + } - return super.defineClass(name, byteCode.getByteCode(), 0, byteCode.getByteCode().length); + private Class doFindClass(String name) throws ClassNotFoundException { + if (null == compiler) { + return null; + } + List classpathList = compiler.getClasspathList(); + if (CollectionUtil.isEmpty(classpathList)) { + return null; + } + String packageName = ""; + if (name.lastIndexOf(".") != -1) { + packageName = name.substring(0, name.lastIndexOf(".")); + } + for (String path : classpathList) { + try { + URL url = new URL("file:" + path); + if (path.endsWith(".jar")) { + url = new URL("jar:file:" + path + "!/"); + } + Set> classSet = ClassUtil.scan(packageName, url); + if (CollectionUtil.isEmpty(classSet)) { + continue; + } + Optional> classOptional = classSet.stream().filter(c -> c.getName().equals(name)).findFirst(); + if (classOptional.isPresent()) { + return classOptional.get(); + } + } catch (Exception e) { + // ignore + } + } + return null; } public Map> getClasses() throws ClassNotFoundException {