Skip to content

Commit 34c3337

Browse files
committed
fix classloader
1 parent b96677e commit 34c3337

File tree

2 files changed

+21
-38
lines changed

2 files changed

+21
-38
lines changed
Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
package io.arex.agent.bootstrap.util;
22

3-
import io.arex.agent.bootstrap.constants.ConfigConstants;
4-
53
import java.io.File;
64
import java.io.FileOutputStream;
75
import java.io.IOException;
86
import java.io.InputStream;
9-
import java.lang.reflect.InvocationTargetException;
107
import java.lang.reflect.Method;
118
import java.net.URL;
12-
import java.net.URLClassLoader;
139
import java.security.AccessController;
1410
import java.security.PrivilegedAction;
11+
import java.util.function.BiConsumer;
1512
import java.util.jar.JarEntry;
1613
import java.util.jar.JarFile;
1714

1815
public class JarUtils {
1916
private static Method addURL;
2017
private static final File TMP_FILE = new File(AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty("java.io.tmpdir")));
2118
private static final String AREX_TEMP_DIR = TMP_FILE.getAbsolutePath() + File.separator + "arex";
19+
public static BiConsumer<ClassLoader, File> addJarToSystemClassLoader = (classLoader, file) -> {
20+
};
2221

2322
static {
2423
try {
@@ -28,10 +27,11 @@ public class JarUtils {
2827
System.err.println("Failed to get addURL method from URLClassLoader");
2928
}
3029
}
30+
3131
public static File extractNestedJar(JarFile file, JarEntry entry, String entryName) throws IOException {
3232
File outputFile = createFile(AREX_TEMP_DIR + File.separator + entryName);
33-
try(InputStream inputStream = file.getInputStream(entry);
34-
FileOutputStream outputStream = new FileOutputStream(outputFile)) {
33+
try (InputStream inputStream = file.getInputStream(entry);
34+
FileOutputStream outputStream = new FileOutputStream(outputFile)) {
3535
byte[] buffer = new byte[1024];
3636
int length;
3737
while ((length = inputStream.read(buffer)) > 0) {
@@ -54,44 +54,20 @@ private static File createFile(String path) throws IOException {
5454
}
5555

5656
/**
57-
* tomcat jdk <= 8, classLoader is ParallelWebappClassLoader, ClassLoader.getSystemClassLoader() is Launcher$AppClassLoader
58-
* jdk > 8, classLoader is ParallelWebappClassLoader, ClassLoader.getSystemClassLoader() is ClassLoaders$AppClassLoader
57+
* Java Instrumentation.appendToSystemClassLoaderSearch() method is compatible across JDK versions, including JDK 8 through JDK 17. Here’s a detailed breakdown of its compatibility:
58+
* 1. JDK 8 Compatibility
59+
* • 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.
60+
* • 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.
61+
* 2. JDK 9+ (including JDK 17) Compatibility
62+
* • 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.
63+
* • 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.
5964
*/
6065
public static void appendToClassLoaderSearch(ClassLoader classLoader, File jarFile) {
6166
try {
62-
if (classLoader instanceof URLClassLoader) {
63-
addURL.invoke(classLoader, jarFile.toURI().toURL());
64-
}
65-
66-
/*
67-
* Due to Java 8 vs java 9+ incompatibility issues
68-
* See https://stackoverflow.com/questions/46694600/java-9-compatability-issue-with-classloader-getsystemclassloader/51584718
69-
*/
70-
ClassLoader urlClassLoader = ClassLoader.getSystemClassLoader();
71-
if (!(urlClassLoader instanceof URLClassLoader)) {
72-
try (URLClassLoader tempClassLoader = new URLClassLoader(new URL[] {jarFile.toURI().toURL()}, urlClassLoader)) {
73-
addURL.invoke(tempClassLoader, jarFile.toURI().toURL());
74-
}
75-
} else {
76-
addURL.invoke(urlClassLoader, jarFile.toURI().toURL());
77-
}
78-
appendToAppClassLoaderSearch(classLoader, jarFile);
67+
addJarToSystemClassLoader.accept(classLoader, jarFile);
7968
} catch (Exception e) {
8069
System.err.printf("appendToClassLoaderSearch failed, classLoader: %s, jarFile: %s%n",
8170
classLoader.getClass().getName(), jarFile.getAbsolutePath());
8271
}
8372
}
84-
85-
/**
86-
* append jar jdk.internal.loader.ClassLoaders.AppClassLoader
87-
* if java version >= 11 need add jvm option:--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
88-
*/
89-
private static void appendToAppClassLoaderSearch(ClassLoader classLoader, File jarFile) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
90-
Class<? extends ClassLoader> loaderClass = classLoader.getClass();
91-
if (JdkUtils.isJdk11OrHigher() && ConfigConstants.APP_CLASSLOADER_NAME.equalsIgnoreCase(loaderClass.getName())) {
92-
Method classPathMethod = loaderClass.getDeclaredMethod("appendToClassPathForInstrumentation", String.class);
93-
classPathMethod.setAccessible(true);
94-
classPathMethod.invoke(classLoader, jarFile.getPath());
95-
}
96-
}
9773
}

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 = (classLoader, 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
}

0 commit comments

Comments
 (0)