Merge "Fix unsafe weak reference usage in test 141"
diff --git a/test/141-class-unload/expected.txt b/test/141-class-unload/expected.txt
index 11de660..2b77b29 100644
--- a/test/141-class-unload/expected.txt
+++ b/test/141-class-unload/expected.txt
@@ -12,7 +12,6 @@
JNI_OnUnload called
null
loader null false
-loader null false
JNI_OnLoad called
JNI_OnUnload called
null
diff --git a/test/141-class-unload/src/Main.java b/test/141-class-unload/src/Main.java
index 17a6049..9ed8d28 100644
--- a/test/141-class-unload/src/Main.java
+++ b/test/141-class-unload/src/Main.java
@@ -37,8 +37,6 @@
try {
testUnloadClass(constructor);
testUnloadLoader(constructor);
- // Test that we don't unload if we have a Method keeping the class live.
- testNoUnloadInvoke(constructor);
// Test that we don't unload if we have an instance.
testNoUnloadInstance(constructor);
// Test JNI_OnLoad and JNI_OnUnload.
@@ -79,10 +77,10 @@
}
private static void testUnloadClass(Constructor constructor) throws Exception {
- WeakReference<Class> klass = setUpUnloadClass(constructor);
+ WeakReference<Class> klass = setUpUnloadClassWeak(constructor);
// No strong references to class loader, should get unloaded.
Runtime.getRuntime().gc();
- WeakReference<Class> klass2 = setUpUnloadClass(constructor);
+ WeakReference<Class> klass2 = setUpUnloadClassWeak(constructor);
Runtime.getRuntime().gc();
// If the weak reference is cleared, then it was unloaded.
System.out.println(klass.get());
@@ -99,12 +97,14 @@
}
private static void testStackTrace(Constructor constructor) throws Exception {
- WeakReference<Class> klass = setUpUnloadClass(constructor);
- Method stackTraceMethod = klass.get().getDeclaredMethod("generateStackTrace");
- Throwable throwable = (Throwable) stackTraceMethod.invoke(klass.get());
+ Class klass = setUpUnloadClass(constructor);
+ WeakReference<Class> weak_klass = new WeakReference(klass);
+ Method stackTraceMethod = klass.getDeclaredMethod("generateStackTrace");
+ Throwable throwable = (Throwable) stackTraceMethod.invoke(klass);
stackTraceMethod = null;
+ klass = null;
Runtime.getRuntime().gc();
- boolean isNull = klass.get() == null;
+ boolean isNull = weak_klass.get() == null;
System.out.println("class null " + isNull + " " + throwable.getMessage());
}
@@ -116,28 +116,37 @@
System.out.println(loader.get());
}
- private static void testNoUnloadInvoke(Constructor constructor) throws Exception {
- WeakReference<ClassLoader> loader =
- new WeakReference((ClassLoader) constructor.newInstance(
- DEX_FILE, LIBRARY_SEARCH_PATH, ClassLoader.getSystemClassLoader()));
- WeakReference<Class> intHolder = new WeakReference(loader.get().loadClass("IntHolder"));
- intHolder.get().getDeclaredMethod("runGC").invoke(intHolder.get());
- boolean isNull = loader.get() == null;
- System.out.println("loader null " + isNull);
+ private static Object testNoUnloadHelper(ClassLoader loader) throws Exception {
+ Class intHolder = loader.loadClass("IntHolder");
+ return intHolder.newInstance();
+ }
+
+ static class Pair {
+ public Pair(Object o, ClassLoader l) {
+ object = o;
+ classLoader = new WeakReference<ClassLoader>(l);
+ }
+
+ public Object object;
+ public WeakReference<ClassLoader> classLoader;
+ }
+
+ private static Pair testNoUnloadInstanceHelper(Constructor constructor) throws Exception {
+ ClassLoader loader = (ClassLoader) constructor.newInstance(
+ DEX_FILE, LIBRARY_SEARCH_PATH, ClassLoader.getSystemClassLoader());
+ Object o = testNoUnloadHelper(loader);
+ return new Pair(o, loader);
}
private static void testNoUnloadInstance(Constructor constructor) throws Exception {
- WeakReference<ClassLoader> loader =
- new WeakReference((ClassLoader) constructor.newInstance(
- DEX_FILE, LIBRARY_SEARCH_PATH, ClassLoader.getSystemClassLoader()));
- WeakReference<Class> intHolder = new WeakReference(loader.get().loadClass("IntHolder"));
- Object o = intHolder.get().newInstance();
+ Pair p = testNoUnloadInstanceHelper(constructor);
Runtime.getRuntime().gc();
- boolean isNull = loader.get() == null;
+ // If the class loader was unloded too early due to races, just pass the test.
+ boolean isNull = p.classLoader.get() == null;
System.out.println("loader null " + isNull);
}
- private static WeakReference<Class> setUpUnloadClass(Constructor constructor) throws Exception {
+ private static Class setUpUnloadClass(Constructor constructor) throws Exception {
ClassLoader loader = (ClassLoader) constructor.newInstance(
DEX_FILE, LIBRARY_SEARCH_PATH, ClassLoader.getSystemClassLoader());
Class intHolder = loader.loadClass("IntHolder");
@@ -149,7 +158,12 @@
setValue.invoke(intHolder, 2);
System.out.println((int) getValue.invoke(intHolder));
waitForCompilation(intHolder);
- return new WeakReference(intHolder);
+ return intHolder;
+ }
+
+ private static WeakReference<Class> setUpUnloadClassWeak(Constructor constructor)
+ throws Exception {
+ return new WeakReference<Class>(setUpUnloadClass(constructor));
}
private static WeakReference<ClassLoader> setUpUnloadLoader(Constructor constructor,