On 9/12/14 1:55 PM, Peter Levart 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;
         }
     }

yes - that's what I'm calling the additional complexity ;-)

-- daniel



(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