Last active
March 2, 2016 21:04
-
-
Save raphw/910177d930ab98998968 to your computer and use it in GitHub Desktop.
Weak parent class loader test
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
public class Bar { | |
public static Object baz() { | |
return new Object(); | |
} | |
} |
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 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(); | |
} | |
} |
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
public class Foo { | |
} |
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
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