Это дополнительный вопрос от к этому .
В частности, я пытаюсь проверить правильность использования API, который включает вызов close()
для объектов Java, содержащих тяжелые нативныересурсы над JNI.Чтобы повторить этот вопрос, это необходимо как в , так и в тестах, а также в производственных тестах, потому что ресурсы просачиваются из одного тестового набора в другой и в производство, потому что, собственно, собственные ресурсы следует просто распоряжаться контролируемым образом.
Код (все такие 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
бесполезен). Если да, то как я могу уведомить о результатах моей проверки?