Skip to content

Instantly share code, notes, and snippets.

@raphw
Last active March 2, 2016 21:04
Show Gist options
  • Save raphw/910177d930ab98998968 to your computer and use it in GitHub Desktop.
Save raphw/910177d930ab98998968 to your computer and use it in GitHub Desktop.
Weak parent class loader test
public class Bar {
public static Object baz() {
return new Object();
}
}
import net.bytebuddy.test.utility.ClassFileExtraction;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
public class ClassLoaderRelease {
public static void main(String[] args) throws Exception {
doAssert(Bar.class);
doAssert(Qux.class);
}
private static void doAssert(Class<?> type) throws Exception {
System.out.println("Running test for referencing of " + type);
ClassLoader classLoader = new WeakParentClassLoader(new SingleTypeClassLoader(Foo.class), type);
Class<?> gcRoot = classLoader.loadClass(type.getName());
Method method = gcRoot.getDeclaredMethod("baz");
if (method.invoke(null) == null) {
throw new AssertionError();
}
System.gc();
System.runFinalization();
Thread.sleep(1000L);
System.out.println("GC root: " + gcRoot);
System.out.println("-----------------------------------");
}
}
class SingleTypeClassLoader extends ClassLoader {
private final Class<?> type;
public SingleTypeClassLoader(Class<?> type) {
super(null);
this.type = type;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (type.getName().equals(name)) {
try {
byte[] binary = ClassFileExtraction.extract(type);
return defineClass(name, binary, 0, binary.length);
} catch (IOException e) {
throw new AssertionError("oops...");
}
}
return super.findClass(name);
}
@Override
protected void finalize() throws Throwable {
if (getClass() == SingleTypeClassLoader.class) {
System.out.println("Finalized " + this);
}
super.finalize();
}
}
class WeakParentClassLoader extends SingleTypeClassLoader {
private final WeakReference<ClassLoader> parent;
public WeakParentClassLoader(ClassLoader parent, Class<?> type) {
super(type);
this.parent = new WeakReference<ClassLoader>(parent);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
ClassLoader classLoader = parent.get();
if (classLoader != null) {
try {
return classLoader.loadClass(name);
} catch (ClassNotFoundException e) {
// attempt self
}
}
return super.loadClass(name);
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
}
public class Foo {
}
public class Qux {
public static Object baz() {
return new Foo();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment