Skip to content

Commit c78262a

Browse files
committed
fix classloader
1 parent b96677e commit c78262a

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

arex-agent-bootstrap/src/main/java/io/arex/agent/bootstrap/util/AdviceClassesCollector.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ private byte[] getBytes(String name, ClassLoader loader) throws IOException {
121121
return locator.locate(name).resolve();
122122
}
123123

124+
public void appendToSystemClassLoaderSearch(String jarPackageName) {
125+
appendToClassLoaderSearch(jarPackageName, null);
126+
}
124127
public void appendToClassLoaderSearch(String jarPackageName, ClassLoader loader) {
125128
List<String> filePathList = THIRD_PARTY_NESTED_JARS_PATH_MAP.get(jarPackageName);
126129
if (CollectionUtil.isEmpty(filePathList)) {
@@ -130,7 +133,11 @@ public void appendToClassLoaderSearch(String jarPackageName, ClassLoader loader)
130133
for (String filePath : filePathList) {
131134
JarEntry jarEntry = agentJarFile.getJarEntry(filePath);
132135
File extractNestedJar = JarUtils.extractNestedJar(agentJarFile, jarEntry, filePath);
133-
JarUtils.appendToClassLoaderSearch(loader, extractNestedJar);
136+
if (loader == null) {
137+
JarUtils.appendToSystemClassLoaderSearch(extractNestedJar);
138+
}else{
139+
JarUtils.appendToClassLoaderSearch(loader, extractNestedJar);
140+
}
134141
}
135142
} catch (Exception ex) {
136143
System.err.printf("appendToClassLoaderSearch failed, jarPackageName: %s%n", jarPackageName);

arex-agent-bootstrap/src/main/java/io/arex/agent/bootstrap/util/JarUtils.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
import java.net.URLClassLoader;
1313
import java.security.AccessController;
1414
import java.security.PrivilegedAction;
15+
import java.util.function.Consumer;
1516
import java.util.jar.JarEntry;
1617
import java.util.jar.JarFile;
1718

1819
public class JarUtils {
1920
private static Method addURL;
2021
private static final File TMP_FILE = new File(AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty("java.io.tmpdir")));
2122
private static final String AREX_TEMP_DIR = TMP_FILE.getAbsolutePath() + File.separator + "arex";
23+
public static Consumer<File> addJarToSystemClassLoader = file -> {
24+
};
2225

2326
static {
2427
try {
@@ -28,10 +31,11 @@ public class JarUtils {
2831
System.err.println("Failed to get addURL method from URLClassLoader");
2932
}
3033
}
34+
3135
public static File extractNestedJar(JarFile file, JarEntry entry, String entryName) throws IOException {
3236
File outputFile = createFile(AREX_TEMP_DIR + File.separator + entryName);
33-
try(InputStream inputStream = file.getInputStream(entry);
34-
FileOutputStream outputStream = new FileOutputStream(outputFile)) {
37+
try (InputStream inputStream = file.getInputStream(entry);
38+
FileOutputStream outputStream = new FileOutputStream(outputFile)) {
3539
byte[] buffer = new byte[1024];
3640
int length;
3741
while ((length = inputStream.read(buffer)) > 0) {
@@ -53,6 +57,19 @@ private static File createFile(String path) throws IOException {
5357
return file;
5458
}
5559

60+
/**
61+
* Java Instrumentation.appendToSystemClassLoaderSearch() method is compatible across JDK versions, including JDK 8 through JDK 17. Here’s a detailed breakdown of its compatibility:
62+
* 1. JDK 8 Compatibility
63+
* • The appendToSystemClassLoaderSearch() method was introduced as part of the Java Instrumentation API in JDK 6. This means it is fully available and compatible with JDK 8.
64+
* • It allows you to append JARs to the system class loader’s search path, ensuring that classes within those JARs can be loaded by the system class loader.
65+
* 2. JDK 9+ (including JDK 17) Compatibility
66+
* • With JDK 9, the module system (Project Jigsaw) was introduced, which brought significant changes to class loading and the organization of Java’s internal APIs.
67+
* • Despite these changes, appendToSystemClassLoaderSearch() remains compatible and continues to work as expected in JDK 9 and later, including JDK 17. It can still be used to add JARs to the classpath of the system class loader.
68+
*/
69+
public static void appendToSystemClassLoaderSearch(File jarFile) {
70+
addJarToSystemClassLoader.accept(jarFile);
71+
}
72+
5673
/**
5774
* tomcat jdk <= 8, classLoader is ParallelWebappClassLoader, ClassLoader.getSystemClassLoader() is Launcher$AppClassLoader
5875
* jdk > 8, classLoader is ParallelWebappClassLoader, ClassLoader.getSystemClassLoader() is ClassLoaders$AppClassLoader
@@ -69,7 +86,7 @@ public static void appendToClassLoaderSearch(ClassLoader classLoader, File jarFi
6986
*/
7087
ClassLoader urlClassLoader = ClassLoader.getSystemClassLoader();
7188
if (!(urlClassLoader instanceof URLClassLoader)) {
72-
try (URLClassLoader tempClassLoader = new URLClassLoader(new URL[] {jarFile.toURI().toURL()}, urlClassLoader)) {
89+
try (URLClassLoader tempClassLoader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()}, urlClassLoader)) {
7390
addURL.invoke(tempClassLoader, jarFile.toURI().toURL());
7491
}
7592
} else {

arex-agent/src/main/java/io/arex/agent/ArexAgent.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ private static void init(Instrumentation inst, String agentArgs) {
4040
*/
4141
installBootstrapJar(inst);
4242
AgentInitializer.initialize(inst, getJarFile(ArexAgent.class), agentArgs, ArexAgent.class.getClassLoader());
43+
io.arex.agent.bootstrap.util.JarUtils.addJarToSystemClassLoader = file -> {
44+
try {
45+
inst.appendToSystemClassLoaderSearch(new JarFile(file, false));
46+
} catch (Exception e) {
47+
System.out.printf("%s [AREX] Agent add jar to system classloader error, stacktrace: %s%n", getCurrentTime(), e);
48+
}
49+
};
4350
} catch (Exception ex) {
4451
System.out.printf("%s [AREX] Agent initialize error, stacktrace: %s%n", getCurrentTime(), ex);
4552
}

arex-instrumentation-api/src/main/java/io/arex/inst/runtime/listener/EventProcessor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ private static void addEnterLog() {
7474
*/
7575
private static void initSerializer(ClassLoader contextClassLoader) {
7676
if (!existJacksonDependency) {
77-
AdviceClassesCollector.INSTANCE.appendToClassLoaderSearch("jackson",
78-
contextClassLoader);
77+
AdviceClassesCollector.INSTANCE.appendToSystemClassLoaderSearch("jackson");
7978
}
8079
final List<StringSerializable> serializableList = ServiceLoader.load(StringSerializable.class, contextClassLoader);
8180
Serializer.builder(serializableList).build();

0 commit comments

Comments
 (0)