Skip to content

Instantly share code, notes, and snippets.

@dmikurube
Last active September 13, 2024 06:54
Show Gist options
  • Save dmikurube/ac1480b4eeaf5e925ead3aec719a5441 to your computer and use it in GitHub Desktop.
Save dmikurube/ac1480b4eeaf5e925ead3aec719a5441 to your computer and use it in GitHub Desktop.
ClassLoader.findLoadedClass
plugins {
id "java"
id "application"
}
repositories {
mavenCentral()
}
group = "io.github.dmikurube"
version = "0.1.0"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}
sourceSets {
main {
java {
srcDir "."
}
}
}
dependencies {
}
application {
mainClass = "Main"
}
run.dependsOn(":jar")
run.doFirst {
copy {
from jar.archiveFile
into rootProject.projectDir
}
}
run {
systemProperty "sub", jar.archiveFile.get().getAsFile().getPath().toString()
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class LoadedClassFinder extends ClassLoader {
static synchronized Class<?> findFrom(final ClassLoader classLoader, final String name) {
final Method findLoadedClass;
try {
findLoadedClass = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
} catch (final NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
findLoadedClass.setAccessible(true);
try {
final Object classObject;
try {
classObject = findLoadedClass.invoke(classLoader, name);
} catch (final IllegalAccessException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
if (classObject == null) {
return null;
}
if (classObject instanceof Class) {
return (Class<?>) classObject;
} else {
throw new RuntimeException();
}
} finally {
findLoadedClass.setAccessible(false);
}
}
}
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
public class Main {
public static void main(final String[] args) throws Exception {
final String sub = System.getProperty("sub");
if (sub == null) {
throw new RuntimeException("Set the system property \"sub\".");
}
System.out.println(sub);
final ArrayList<URL> urls = new ArrayList<>();
urls.add(Paths.get(sub).toUri().toURL());
final MyClassLoader classloader = new MyClassLoader(urls, Main.class.getClassLoader());
final Class<?> klass0 = LoadedClassFinder.findFrom(Main.class.getClassLoader(), "Main");
printClass(klass0);
final Class<?> klass1 = classloader.findLoadedClassPublic("Main");
printClass(klass1);
final Class<?> klass2 = classloader.loadClass("Main");
printClass(klass2);
final Class<?> klass3 = classloader.findLoadedClassPublic("Main");
printClass(klass3);
final Class<?> klass4 = classloader.loadClassInThisClassLoader("Main");
printClass(klass4);
final Class<?> klass5 = classloader.findLoadedClassPublic("Main");
printClass(klass5);
}
private static void printClass(final Class<?> klass) {
System.out.println(klass);
if (klass != null) {
System.out.println(klass.hashCode());
} else {
System.out.println("N/A");
}
}
}
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Vector;
public class MyClassLoader extends URLClassLoader {
public MyClassLoader(final Collection<URL> jarUrls, final ClassLoader parent) {
super(jarUrls.toArray(new URL[0]), parent);
}
public Class<?> findLoadedClassPublic(final String name) {
return this.findLoadedClass(name);
}
public Class<?> loadClassInThisClassLoader(final String name) throws ClassNotFoundException {
synchronized (this.getClassLoadingLock(name)) {
final Class<?> loadedClass = this.findLoadedClass(name);
if (loadedClass != null) {
return loadedClass;
}
return this.findClass(name);
}
}
private Class<?> resolveClass(final Class<?> clazz, final boolean resolve) {
if (resolve) {
this.resolveClass(clazz);
}
return clazz;
}
}
@dmikurube
Copy link
Author

dmikurube commented Sep 13, 2024

$ ./gradlew run
/home/.../classloader/build/libs/classloader-0.1.0.jar
class Main
589431969
null
N/A
class Main
589431969
null
N/A
class Main
21685669
class Main
21685669

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment