Почему действие Cleaner не вызывается? - PullRequest
0 голосов
/ 12 февраля 2019

Это дополнительный вопрос от к этому .

В частности, я пытаюсь проверить правильность использования 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 бесполезен). Если да, то как я могу уведомить о результатах моей проверки?

...