Last active
September 13, 2024 06:54
-
-
Save dmikurube/ac1480b4eeaf5e925ead3aec719a5441 to your computer and use it in GitHub Desktop.
ClassLoader.findLoadedClass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Author
dmikurube
commented
Sep 13, 2024
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment