解决以jar方式启动,动态编译类找不到符号的问题.

This commit is contained in:
aoshiguchen
2022-09-10 00:49:55 +08:00
parent 7c6dc2eb00
commit 9e0512f1a4
6 changed files with 93 additions and 38 deletions
@@ -91,10 +91,10 @@ public class AsgcProxyFactory implements ProxyFactory {
}
private <T> Class<T> compile(ProxyClass proxyClass) throws ClassNotFoundException {
if (SystemUtil.isStartupFromJar() || GlobalConfig.isSaveGeneratorCode()) {
compiler.compileToFile(proxyClass);
return (Class<T>)classLoader.loadProxyClass(proxyClass);
}
// if (SystemUtil.isStartupFromJar() || GlobalConfig.isSaveGeneratorCode()) {
// compiler.compileToFile(proxyClass);
// return (Class<T>)classLoader.loadProxyClass(proxyClass);
// }
compiler.compile(proxyClass);
return (Class<T>)classLoader.loadProxyClass(proxyClass);
}
@@ -120,6 +120,9 @@ public class ProxyCompiler {
}
}
list.add(GlobalConfig.getGeneratorCodeSavePath() + "BOOT-INF/classes/");
if (SystemUtil.isStartupFromJar()) {
list.add(SystemUtil.getCurrentJarFilePath());
}
return list.stream().collect(Collectors.joining(File.pathSeparator));
}
@@ -138,6 +141,7 @@ public class ProxyCompiler {
"Visit https://jfinal.com/doc/4-8 for details \n");
}
System.out.println("=====> classpath:" + getOptions());
DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<>();
try (MyJavaFileManager javaFileManager = new MyJavaFileManager(compiler.getStandardFileManager(collector, null, null))) {
@@ -128,39 +128,50 @@ public class ClassUtil {
}
log.info("开始进行类扫描,扫描包:{}", packageName);
Set<Class<?>> classes = new HashSet<>();
String packagePath = packageName.replace(".", "/");
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("");
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread().getContextClassLoader());
log.info(url.toString());
String protocol = url.getProtocol();
if ("jar".equals(protocol)) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String name = jarEntry.getName();
int index = name.indexOf(packagePath);
if (index != -1 && name.endsWith(".class")) {
String replace = name.substring(index, name.length() - 6).replace("/", ".");
Class clazz = urlClassLoader.loadClass(replace);
log.debug("scan class {}", clazz.getName());
classes.add(clazz);
}
}
} else if ("file".endsWith(protocol)) {
String path = url.getPath();
String targetPath = path + "/" + packagePath;
addClasses(targetPath, classes, packageName);
}
classes.addAll(scan(packageName, resources.nextElement()));
}
if (SystemUtil.isStartupFromJar()) {
classes.addAll(scan(packageName, new URL("jar:file:" + SystemUtil.getCurrentJarFilePath() + "!/")));
}
log.info("扫描完毕,包:{}下一共有:{}个类", packageName, classes.size());
classesCache.set(packageName, classes);
return classes;
}
public static Set<Class<?>> scan(String packageName, URL url) throws IOException, ClassNotFoundException {
Set<Class<?>> result = new HashSet<>();
if (null == url) {
return result;
}
String packagePath = packageName.replace(".", "/");
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread().getContextClassLoader());
log.info(url.toString());
String protocol = url.getProtocol();
if ("jar".equals(protocol)) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String name = jarEntry.getName();
int index = name.indexOf(packagePath);
if (index != -1 && name.endsWith(".class")) {
String replace = name.substring(index, name.length() - 6).replace("/", ".");
Class clazz = urlClassLoader.loadClass(replace);
log.debug("scan class {}", clazz.getName());
result.add(clazz);
}
}
} else if ("file".endsWith(protocol)) {
String path = url.getPath();
String targetPath = path + "/" + packagePath;
addClasses(targetPath, result, packageName);
}
return result;
}
private static void addClasses(String path, Set<Class<?>> classes, String packageName) throws ClassNotFoundException {
File[] files = new File(path).listFiles(new FileFilter() {
@Override
@@ -88,12 +88,12 @@ public class AsgcCompilerTest {
compiler.addClasspath("/Users/yangwen/my/tmp/java");
compiler.addClasspath("/Users/yangwen/my/tmp/java/asgc-package-lab1-1.0-SNAPSHOT.jar");
String code = "package a.b;\n" +
"import fun.asgc.lab.pkg.lab1.Dog1;\n" +
"import fun.asgc.lab.pkg.lab1.Dog;\n" +
"import fun.asgc.cptest.Player;\n" +
"public class RadioPlayer implements Player {\n" +
"\tpublic void play() {\n" +
// "\t\tSystem.out.println(Dog.class);\n" +
// "\t\tSystem.out.println(new Dog(\"大黄\").eat(\"骨头\"));\n" +
"\t\tSystem.out.println(Dog.class);\n" +
"\t\tSystem.out.println(new Dog(\"大黄\").eat(\"骨头\"));\n" +
"\t\tSystem.out.println(\"收音机播放\");\n" +
"\t}\n" +
"}\n";
@@ -25,6 +25,8 @@ import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -71,4 +73,12 @@ public class ClassUtilTest {
}
}
@Test
public void scan() throws Exception {
String path = "jar:file:/Users/yangwen/my/tmp/java/neutrino-proxy-server-1.0-SNAPSHOT-jar-with-dependencies.jar!/";
URL url = new URL(path);
Set<Class<?>> c = ClassUtil.scan("fun.asgc.neutrino.proxy.server", url);
System.out.println(c);
}
}
+36 -6
View File
@@ -32,20 +32,50 @@
</dependency>
</dependencies>
<!-- <build>-->
<!-- <finalName>${artifactId}</finalName>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- <version>2.1.3.RELEASE</version>-->
<!-- <configuration>-->
<!-- <executable>true</executable>-->
<!-- <mainClass>fun.asgc.neutrino.proxy.server.ProxyServer</mainClass>-->
<!-- <classifier>exec</classifier>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <goals>-->
<!-- <goal>repackage</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
<build>
<finalName>${artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.3.RELEASE</version>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<mainClass>fun.asgc.neutrino.proxy.server.ProxyServer</mainClass>
<archive>
<manifest>
<!--这里指定要运行的main类-->
<mainClass>fun.asgc.neutrino.proxy.server.ProxyServer</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>repackage</goal>
<goal>single</goal>
</goals>
</execution>
</executions>