这是此问题的后续问题。
具体来说,我正在尝试验证 API 的正确使用,该 API 涉及close()
通过 JNI 调用持有大量本机资源的 Java 对象。重申一下这个问题,在测试和生产中都需要这样做,因为资源从一个测试用例泄漏到另一个测试用例和生产中,因为本地资源应该以受控方式处理。
代码(我想要处理的所有此类 Java 对象都将扩展 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");
}
}
}
}
为什么不调用清洁器操作?我在控制台中既没有看到“JPeer 已关闭”,也没有看到“JPeer 未关闭”。无法从更清洁的操作中打印某些内容是个问题吗?(我知道从那里抛出的异常会被忽略,所以AssertionError
没用)如果是这样,我如何通知我的验证结果?