Hi Peter, I like the LHM (personal favorite data structure) approach with the dual-purpose key. Stanimir On Fri, Sep 12, 2014 at 2:55 PM, Peter Levart <peter.levart@gmail.com> wrote:
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