Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7092981

LogManager.reset should clear properties after loggers are reset.

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 6u26
    • core-libs

      A DESCRIPTION OF THE REQUEST :
      On shutdown of the JVM, the LogManager$Cleaner will call LogManager.reset. LogManager.reset will first clear all the properties assigned in the LogManager then walks all the loggers and calls close on each attached handler. Because the LogManager properties are cleared first, Handler.close is not able to perform any valid LogManager.getProperty calls.

      JUSTIFICATION :
      It is inconsistent that Handler.close is able to get properties from a direct call but unable to get properties during an indirect call from LogManager.reset. There is no way to perform lazy lookups during close so values have to be cached on startup which hurts the load times of an application. For some handlers that are adapters for other APIs there is no way to explictly know what parameters are required to be cached at startup since there is no way to iterate over LogManager keys.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Handler.close should always be able to getProperties from the LogManager during a reset.
      ACTUAL -
      LogManager.getProperty will return null.

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.util.Properties;
      import java.util.logging.ErrorManager;
      import java.util.logging.Handler;
      import java.util.logging.LogManager;
      import java.util.logging.LogRecord;
      import java.util.logging.Logger;

      public class Cleared extends Handler {

          private static final Logger logger = Logger.getLogger("Cleared");

          public static void main(String[] args) throws IOException {
              Properties props = new Properties();
              props.put(Cleared.class.getName(), logger.getClass().getName());
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              props.store(out, "");
              ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
              LogManager.getLogManager().readConfiguration(in);

              logger.addHandler(new Cleared());
          }

          public Cleared() {
              try {
                  check();
              } catch(RuntimeException re) {
                  this.reportError("", re, ErrorManager.OPEN_FAILURE);
              }
          }

          @Override
          public void publish(LogRecord record) {
          }

          @Override
          public void flush() {
          }

          @Override
          public void close() throws SecurityException {
              try {
                  check();
              } catch(RuntimeException re) {
                  this.reportError("", re, ErrorManager.CLOSE_FAILURE);
              }
          }

          private void check() {
              String p = LogManager.getLogManager().getProperty(getClass().getName());
              if (!logger.getClass().getName().equals(p)) {
                  throw new IllegalStateException();
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Create a LogManager subclass and override reset to first close and remove all handlers then perform the super action.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: