Skip to content

Commit

Permalink
Load class from class path if not found
Browse files Browse the repository at this point in the history
  • Loading branch information
secfree committed Oct 17, 2024
1 parent c0e9380 commit ad86e68
Showing 1 changed file with 70 additions and 0 deletions.
70 changes: 70 additions & 0 deletions agent/src/main/java/com/taobao/arthas/agent/ArthasClassloader.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package com.taobao.arthas.agent;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
* @author beiwei30 on 09/12/2016.
Expand All @@ -28,9 +34,73 @@ protected synchronized Class<?> loadClass(String name, boolean resolve) throws C
resolveClass(aClass);
}
return aClass;
} catch (ClassNotFoundException e) {
// ignore
}

try {
Class<?> aClass = loadClassFromClassPath(name);
if (resolve) {
resolveClass(aClass);
}
return aClass;
} catch (Exception e) {
// ignore
}

return super.loadClass(name, resolve);
}

private Class<?> loadClassFromClassPath(String name) throws ClassNotFoundException {
String classpath = System.getProperty("java.class.path");
String[] paths = classpath.split(File.pathSeparator);

byte[] classData = null;
for (String path : paths) {
if (path.endsWith(".jar")) {
classData = loadClassDataFromJar(name, path);
} else {
classData = loadClassDataFromDirectory(name, path);
}

if (classData != null) {
break;
}
}

if (classData == null) {
throw new ClassNotFoundException("Class " + name + " not found in CLASSPATH.");
}
return defineClass(name, classData, 0, classData.length);
}

private byte[] loadClassDataFromDirectory(String className, String classpath) {
String path = classpath + File.separator
+ className.replace('.', File.separatorChar) + ".class";
try (InputStream input = new FileInputStream(path)) {
byte[] buffer = new byte[input.available()];
input.read(buffer);
return buffer;
} catch (IOException e) {
return null;
}
}

private byte[] loadClassDataFromJar(String className, String jarPath) {
String entryName = className.replace('.', '/') + ".class";
try (JarFile jarFile = new JarFile(jarPath)) {
JarEntry entry = jarFile.getJarEntry(entryName);
if (entry == null) {
return null;
}

try (InputStream input = jarFile.getInputStream(entry)) {
byte[] buffer = new byte[(int) entry.getSize()];
input.read(buffer);
return buffer;
}
} catch (IOException e) {
return null;
}
}
}

0 comments on commit ad86e68

Please sign in to comment.