Why is Cleaner action not invoked?

蹲街弑〆低调 提交于 2019-12-11 17:36:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!