On 09/12/2014 12:45 PM, Daniel Fuchs wrote:
However the listeners are to be invoked in the same order they have been
added.

I am still unconvinced this is worth the additional
complexity it would bring to the implementation.
The deprecated methods were using HashMap to store listeners,
and therefore the order in which listeners were invoked was also
undefined. Nobody has ever complained.

What about using a synchronized LinkedHashMap<ListenerAction, ListenerAction>() with the following double-purpose inner class:

private static final class ListenerAction implements PrivilegedAction<Void> {
        private final Runnable listener;
        private final AccessControlContext acc;

        ListenerAction(Runnable listener, AccessControlContext acc) {
            this.listener = listener;
            this.acc = acc;
        }

        void invoke() {
            if (acc == null) {
                run();
            } else {
                AccessController.doPrivileged(this, acc);
            }
        }

        // not to be run() directly - use invoke() instead
        @Override
        public Void run() {
            listener.run();
            return null;
        }

        @Override
        public int hashCode() {
            return System.identityHashCode(listener);
        }

        @Override
        public boolean equals(Object obj) {
            return (obj instanceof ListenerAction) &&
                   ((ListenerAction) obj).listener == listener;
        }
    }



(http://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/file/3ae82f0c6b31/src/share/classes/java/util/logging/LogManager.java#l1431)


I'd rather run the listeners in try/catch and throw the 1st exception at
the end.
Defining the 1st however requires obeying the order the listeners have
been added.
As far as I see there is no documentation how the listeners are supposed
to behave or be invoked.

We could do that - invoke all listeners and rethrow the exception
caught by the first listener that failed (on the basis that if any other
listener subsequently fails it may be because the previous listener
has left the system in an inconsistent state, and that therefore
the first exception caught has 'more value' than the others).

I am not completely convinced this is a better behavior than
simply stopping invoking listeners at the first exception.
I wonder if there would be a good wording to say that listeners
are not supposed to throw, but that if they do, the exceptions
will be propagated...

You're probably right. But in case you changed your mind, you could rethrow the 1st exception thrown, with possible further exceptions added to it a suppressed exceptions...

Regards, Peter


best regards,

-- daniel

Reply via email to