问题
This is a follow-up question from this one.
Specifically I'm trying to verify correct use of an API which involves calling close()
on Java objects holding heavy native resources over JNI. To re-iterate from that question, this is needed in both tests and production, tests because resources leak from one testcase to another and in production because, well, native resources should just be disposed in controlled manner.
The code (all such Java objects that I want disposed would extend JPeer):
public class JPeer implements AutoCloseable {
private final long nativeHandle_ = ....
private final Verifier closeVerifier_;
private static final Cleaner cleaner_ = Cleaner.create();
protected JPeer() {
closeVerifier_ = new Verifier();
cleaner_.register(this, closeVerifier_);
}
@SuppressWarnings("unchecked")
@Override
public final void close() {
if (closed())
throw new AssertionError("JPeer already closed");
..... // doing dispose over JNI
closeVerifier_.markDone();
}
// @SuppressWarnings("deprecation")
// @Override
// protected final void finalize() {
// if (!closed()) {
// // due to threading considerations with JNI, we shouldn't destroy here, we rely on user to destroy from construction thread
// // TODO finalize() never called, how to assert closure?
// throw new AssertionError("JPeer was not closed, native object leaking");
// }
// }
private static final class Verifier implements Runnable {
volatile boolean done_ = false;
public void markDone() {
done_ = true;
}
@Override
public void run() {
if (!done_) {
// due to threading considerations with JNI, we shouldn't destroy here, we rely on user to destroy from construction thread
System.err.println("Verifier: JPeer was not closed, native object leaking");
throw new AssertionError("Verifier: JPeer was not closed, native object leaking");
}
else {
System.out.println("Verifier: JPeer was closed");
}
}
}
}
Why is the cleaner action not invoked? I see neither "JPeer was closed" nor "JPeer not closed" in the console. It is a problem with not being able to print something from a cleaner action? (I know exceptions thrown from there are ignored so the AssertionError
is useless) If so, how can I notify the outcome of my verification?
来源:https://stackoverflow.com/questions/54651773/why-is-cleaner-action-not-invoked