< prev index next >

jdk/src/java.logging/share/classes/java/util/logging/LogManager.java

Print this page




2531      * <p>
2532      * It is recommended that listeners do not throw errors or exceptions.
2533      *
2534      * If a listener terminates with an uncaught error or exception then
2535      * the first exception will be propagated to the caller of
2536      * {@link #readConfiguration()} (or {@link #readConfiguration(java.io.InputStream)})
2537      * after all listeners have been invoked.
2538      *
2539      * @implNote If more than one listener terminates with an uncaught error or
2540      * exception, an implementation may record the additional errors or
2541      * exceptions as {@linkplain Throwable#addSuppressed(java.lang.Throwable)
2542      * suppressed exceptions}.
2543      *
2544      * @param listener A configuration listener that will be invoked after the
2545      *        configuration changed.
2546      * @return This LogManager.
2547      * @throws SecurityException if a security manager exists and if the
2548      * caller does not have LoggingPermission("control").
2549      * @throws NullPointerException if the listener is null.
2550      *
2551      * @since 1.9
2552      */
2553     public LogManager addConfigurationListener(Runnable listener) {
2554         final Runnable r = Objects.requireNonNull(listener);
2555         checkPermission();
2556         final SecurityManager sm = System.getSecurityManager();
2557         final AccessControlContext acc =
2558                 sm == null ? null : AccessController.getContext();
2559         final PrivilegedAction<Void> pa =
2560                 acc == null ? null : () -> { r.run() ; return null; };
2561         final Runnable pr =
2562                 acc == null ? r : () -> AccessController.doPrivileged(pa, acc);
2563         // Will do nothing if already registered.
2564         listeners.putIfAbsent(r, pr);
2565         return this;
2566     }
2567 
2568     /**
2569      * Removes a previously registered configuration listener.
2570      *
2571      * Returns silently if the listener is not found.
2572      *
2573      * @param listener the configuration listener to remove.
2574      * @throws NullPointerException if the listener is null.
2575      * @throws SecurityException if a security manager exists and if the
2576      * caller does not have LoggingPermission("control").
2577      *
2578      * @since 1.9
2579      */
2580     public void removeConfigurationListener(Runnable listener) {
2581         final Runnable key = Objects.requireNonNull(listener);
2582         checkPermission();
2583         listeners.remove(key);
2584     }
2585 
2586     private void invokeConfigurationListeners() {
2587         Throwable t = null;
2588 
2589         // We're using an IdentityHashMap because we want to compare
2590         // keys using identity (==).
2591         // We don't want to loop within a block synchronized on 'listeners'
2592         // to avoid invoking listeners from yet another synchronized block.
2593         // So we're taking a snapshot of the values list to avoid the risk of
2594         // ConcurrentModificationException while looping.
2595         //
2596         for (Runnable c : listeners.values().toArray(new Runnable[0])) {
2597             try {
2598                 c.run();




2531      * <p>
2532      * It is recommended that listeners do not throw errors or exceptions.
2533      *
2534      * If a listener terminates with an uncaught error or exception then
2535      * the first exception will be propagated to the caller of
2536      * {@link #readConfiguration()} (or {@link #readConfiguration(java.io.InputStream)})
2537      * after all listeners have been invoked.
2538      *
2539      * @implNote If more than one listener terminates with an uncaught error or
2540      * exception, an implementation may record the additional errors or
2541      * exceptions as {@linkplain Throwable#addSuppressed(java.lang.Throwable)
2542      * suppressed exceptions}.
2543      *
2544      * @param listener A configuration listener that will be invoked after the
2545      *        configuration changed.
2546      * @return This LogManager.
2547      * @throws SecurityException if a security manager exists and if the
2548      * caller does not have LoggingPermission("control").
2549      * @throws NullPointerException if the listener is null.
2550      *
2551      * @since 9
2552      */
2553     public LogManager addConfigurationListener(Runnable listener) {
2554         final Runnable r = Objects.requireNonNull(listener);
2555         checkPermission();
2556         final SecurityManager sm = System.getSecurityManager();
2557         final AccessControlContext acc =
2558                 sm == null ? null : AccessController.getContext();
2559         final PrivilegedAction<Void> pa =
2560                 acc == null ? null : () -> { r.run() ; return null; };
2561         final Runnable pr =
2562                 acc == null ? r : () -> AccessController.doPrivileged(pa, acc);
2563         // Will do nothing if already registered.
2564         listeners.putIfAbsent(r, pr);
2565         return this;
2566     }
2567 
2568     /**
2569      * Removes a previously registered configuration listener.
2570      *
2571      * Returns silently if the listener is not found.
2572      *
2573      * @param listener the configuration listener to remove.
2574      * @throws NullPointerException if the listener is null.
2575      * @throws SecurityException if a security manager exists and if the
2576      * caller does not have LoggingPermission("control").
2577      *
2578      * @since 9
2579      */
2580     public void removeConfigurationListener(Runnable listener) {
2581         final Runnable key = Objects.requireNonNull(listener);
2582         checkPermission();
2583         listeners.remove(key);
2584     }
2585 
2586     private void invokeConfigurationListeners() {
2587         Throwable t = null;
2588 
2589         // We're using an IdentityHashMap because we want to compare
2590         // keys using identity (==).
2591         // We don't want to loop within a block synchronized on 'listeners'
2592         // to avoid invoking listeners from yet another synchronized block.
2593         // So we're taking a snapshot of the values list to avoid the risk of
2594         // ConcurrentModificationException while looping.
2595         //
2596         for (Runnable c : listeners.values().toArray(new Runnable[0])) {
2597             try {
2598                 c.run();


< prev index next >