Skip to content

Commit 30b804f

Browse files
DbExceptionListener: test with no strong local reference.
1 parent 45da054 commit 30b804f

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

tests/objectbox-java-test/src/test/java/io/objectbox/exception/ExceptionTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.junit.Test;
2020

21+
import java.lang.ref.WeakReference;
2122
import java.util.ArrayList;
2223
import java.util.List;
2324
import java.util.concurrent.atomic.AtomicBoolean;
@@ -46,6 +47,69 @@ public void exceptionListener_closedStore_works() {
4647
store.setDbExceptionListener(e -> System.out.println("This is never called"));
4748
}
4849

50+
private static boolean weakRefListenerCalled = false;
51+
52+
@Test
53+
public void exceptionListener_noLocalRef_works() throws InterruptedException {
54+
// Note: do not use lambda, it would keep a reference to this class
55+
// and prevent garbage collection of the listener.
56+
//noinspection Convert2Lambda
57+
DbExceptionListener listenerNoRef = new DbExceptionListener() {
58+
@Override
59+
public void onDbException(Exception e) {
60+
System.out.println("Listener without strong reference is called");
61+
weakRefListenerCalled = true;
62+
}
63+
};
64+
WeakReference<DbExceptionListener> weakReference = new WeakReference<>(listenerNoRef);
65+
66+
// Set and clear local reference.
67+
store.setDbExceptionListener(listenerNoRef);
68+
//noinspection UnusedAssignment
69+
listenerNoRef = null;
70+
71+
// Try and fail to release weak reference.
72+
int triesClearWeakRef = 5;
73+
while (weakReference.get() != null) {
74+
if (--triesClearWeakRef == 0) break;
75+
System.out.println("Suggesting GC");
76+
System.gc();
77+
//noinspection BusyWait
78+
Thread.sleep(300);
79+
}
80+
assertEquals("Listener weak reference was released", 0, triesClearWeakRef);
81+
82+
// Throw, listener should be called.
83+
weakRefListenerCalled = false;
84+
assertThrows(
85+
DbException.class,
86+
() -> DbExceptionListenerJni.nativeThrowException(store.getNativeStore(), 0)
87+
);
88+
assertTrue(weakRefListenerCalled);
89+
90+
// Remove reference from native side.
91+
store.setDbExceptionListener(null);
92+
93+
// Try and succeed to release weak reference.
94+
triesClearWeakRef = 5;
95+
while (weakReference.get() != null) {
96+
if (--triesClearWeakRef == 0) break;
97+
System.out.println("Suggesting GC");
98+
System.gc();
99+
//noinspection BusyWait
100+
Thread.sleep(300);
101+
}
102+
assertTrue("Listener weak reference was NOT released", triesClearWeakRef > 0);
103+
104+
// Throw, listener should not be called.
105+
weakRefListenerCalled = false;
106+
assertThrows(
107+
DbException.class,
108+
() -> DbExceptionListenerJni.nativeThrowException(store.getNativeStore(), 0)
109+
);
110+
assertFalse(weakRefListenerCalled);
111+
}
112+
49113
@Test
50114
public void exceptionListener_removing_works() {
51115
AtomicBoolean replacedListenerCalled = new AtomicBoolean(false);

0 commit comments

Comments
 (0)