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

Print this page
rev 4793 : 7117249: java.util warnings patches from LJC/Mike Barker


 162     private Logger rootLogger;
 163 
 164     // Have we done the primordial reading of the configuration file?
 165     // (Must be done after a suitable amount of java.lang.System
 166     // initialization has been done)
 167     private volatile boolean readPrimordialConfiguration;
 168     // Have we initialized global (root) handlers yet?
 169     // This gets set to false in readConfiguration
 170     private boolean initializedGlobalHandlers = true;
 171     // True if JVM death is imminent and the exit hook has been called.
 172     private boolean deathImminent;
 173 
 174     static {
 175         AccessController.doPrivileged(new PrivilegedAction<Object>() {
 176                 public Object run() {
 177                     String cname = null;
 178                     try {
 179                         cname = System.getProperty("java.util.logging.manager");
 180                         if (cname != null) {
 181                             try {
 182                                 Class clz = ClassLoader.getSystemClassLoader().loadClass(cname);
 183                                 manager = (LogManager) clz.newInstance();
 184                             } catch (ClassNotFoundException ex) {
 185                                 Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname);
 186                                 manager = (LogManager) clz.newInstance();
 187                             }
 188                         }
 189                     } catch (Exception ex) {
 190                         System.err.println("Could not load Logmanager \"" + cname + "\"");
 191                         ex.printStackTrace();
 192                     }
 193                     if (manager == null) {
 194                         manager = new LogManager();
 195                     }
 196 
 197                     // Create and retain Logger for the root of the namespace.
 198                     manager.rootLogger = manager.new RootLogger();
 199                     manager.addLogger(manager.rootLogger);
 200 
 201                     // Adding the global Logger. Doing so in the Logger.<clinit>
 202                     // would deadlock with the LogManager.<clinit>.
 203                     Logger.global.setLogManager(manager);
 204                     manager.addLogger(Logger.global);
 205 
 206                     // We don't call readConfiguration() here, as we may be running
 207                     // very early in the JVM startup sequence.  Instead readConfiguration
 208                     // will be called lazily in getLogManager().
 209                     return null;
 210                 }
 211             });
 212     }
 213 
 214 
 215     // This private class is used as a shutdown hook.
 216     // It does a "reset" to close all open handlers.
 217     private class Cleaner extends Thread {
 218 
 219         private Cleaner() {
 220             /* Set context class loader to null in order to avoid
 221              * keeping a strong reference to an application classloader.
 222              */
 223             this.setContextClassLoader(null);
 224         }


 398 
 399     // Add new per logger handlers.
 400     // We need to raise privilege here. All our decisions will
 401     // be made based on the logging configuration, which can
 402     // only be modified by trusted code.
 403     private void loadLoggerHandlers(final Logger logger, final String name,
 404                                     final String handlersPropertyName) {
 405         AccessController.doPrivileged(new PrivilegedAction<Object>() {
 406             public Object run() {
 407                 if (logger != rootLogger) {
 408                     boolean useParent = getBooleanProperty(name + ".useParentHandlers", true);
 409                     if (!useParent) {
 410                         logger.setUseParentHandlers(false);
 411                     }
 412                 }
 413 
 414                 String names[] = parseClassNames(handlersPropertyName);
 415                 for (int i = 0; i < names.length; i++) {
 416                     String word = names[i];
 417                     try {
 418                         Class   clz = ClassLoader.getSystemClassLoader().loadClass(word);
 419                         Handler hdl = (Handler) clz.newInstance();
 420                         try {
 421                             // Check if there is a property defining the
 422                             // this handler's level.
 423                             String levs = getProperty(word + ".level");
 424                             if (levs != null) {
 425                                 hdl.setLevel(Level.parse(levs));
 426                             }
 427                         } catch (Exception ex) {
 428                             System.err.println("Can't set level for " + word);
 429                             // Probably a bad level. Drop through.
 430                         }
 431                         // Add this Handler to the logger
 432                         logger.addHandler(hdl);
 433                     } catch (Exception ex) {
 434                         System.err.println("Can't load log handler \"" + word + "\"");
 435                         System.err.println("" + ex);
 436                         ex.printStackTrace();
 437                     }
 438                 }


 765      * Any log level definitions in the new configuration file will be
 766      * applied using Logger.setLevel(), if the target Logger exists.
 767      * <p>
 768      * A PropertyChangeEvent will be fired after the properties are read.
 769      *
 770      * @exception  SecurityException  if a security manager exists and if
 771      *             the caller does not have LoggingPermission("control").
 772      * @exception  IOException if there are IO problems reading the configuration.
 773      */
 774     public void readConfiguration() throws IOException, SecurityException {
 775         checkAccess();
 776 
 777         // if a configuration class is specified, load it and use it.
 778         String cname = System.getProperty("java.util.logging.config.class");
 779         if (cname != null) {
 780             try {
 781                 // Instantiate the named class.  It is its constructor's
 782                 // responsibility to initialize the logging configuration, by
 783                 // calling readConfiguration(InputStream) with a suitable stream.
 784                 try {
 785                     Class clz = ClassLoader.getSystemClassLoader().loadClass(cname);
 786                     clz.newInstance();
 787                     return;
 788                 } catch (ClassNotFoundException ex) {
 789                     Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname);
 790                     clz.newInstance();
 791                     return;
 792                 }
 793             } catch (Exception ex) {
 794                 System.err.println("Logging configuration class \"" + cname + "\" failed");
 795                 System.err.println("" + ex);
 796                 // keep going and useful config file.
 797             }
 798         }
 799 
 800         String fname = System.getProperty("java.util.logging.config.file");
 801         if (fname == null) {
 802             fname = System.getProperty("java.home");
 803             if (fname == null) {
 804                 throw new Error("Can't find java.home ??");
 805             }
 806             File f = new File(fname, "lib");
 807             f = new File(f, "logging.properties");
 808             fname = f.getCanonicalPath();
 809         }


 820 
 821     /**
 822      * Reset the logging configuration.
 823      * <p>
 824      * For all named loggers, the reset operation removes and closes
 825      * all Handlers and (except for the root logger) sets the level
 826      * to null.  The root logger's level is set to Level.INFO.
 827      *
 828      * @exception  SecurityException  if a security manager exists and if
 829      *             the caller does not have LoggingPermission("control").
 830      */
 831 
 832     public void reset() throws SecurityException {
 833         checkAccess();
 834         synchronized (this) {
 835             props = new Properties();
 836             // Since we are doing a reset we no longer want to initialize
 837             // the global handlers, if they haven't been initialized yet.
 838             initializedGlobalHandlers = true;
 839         }
 840         Enumeration enum_ = getLoggerNames();
 841         while (enum_.hasMoreElements()) {
 842             String name = (String)enum_.nextElement();
 843             resetLogger(name);
 844         }
 845     }
 846 
 847 
 848     // Private method to reset an individual target logger.
 849     private void resetLogger(String name) {
 850         Logger logger = getLogger(name);
 851         if (logger == null) {
 852             return;
 853         }
 854         // Close all the Logger's handlers.
 855         Handler[] targets = logger.getHandlers();
 856         for (int i = 0; i < targets.length; i++) {
 857             Handler h = targets[i];
 858             logger.removeHandler(h);
 859             try {
 860                 h.close();
 861             } catch (Exception ex) {
 862                 // Problems closing a handler?  Keep going...


 909      * Any log level definitions in the new configuration file will be
 910      * applied using Logger.setLevel(), if the target Logger exists.
 911      *
 912      * @param ins       stream to read properties from
 913      * @exception  SecurityException  if a security manager exists and if
 914      *             the caller does not have LoggingPermission("control").
 915      * @exception  IOException if there are problems reading from the stream.
 916      */
 917     public void readConfiguration(InputStream ins) throws IOException, SecurityException {
 918         checkAccess();
 919         reset();
 920 
 921         // Load the properties
 922         props.load(ins);
 923         // Instantiate new configuration objects.
 924         String names[] = parseClassNames("config");
 925 
 926         for (int i = 0; i < names.length; i++) {
 927             String word = names[i];
 928             try {
 929                 Class clz = ClassLoader.getSystemClassLoader().loadClass(word);
 930                 clz.newInstance();
 931             } catch (Exception ex) {
 932                 System.err.println("Can't load config class \"" + word + "\"");
 933                 System.err.println("" + ex);
 934                 // ex.printStackTrace();
 935             }
 936         }
 937 
 938         // Set levels on any pre-existing loggers, based on the new properties.
 939         setLevelsOnExistingLoggers();
 940 
 941         // Notify any interested parties that our properties have changed.
 942         changes.firePropertyChange(null, null, null);
 943 
 944         // Note that we need to reinitialize global handles when
 945         // they are first referenced.
 946         synchronized (this) {
 947             initializedGlobalHandlers = false;
 948         }
 949     }


1007     Level getLevelProperty(String name, Level defaultValue) {
1008         String val = getProperty(name);
1009         if (val == null) {
1010             return defaultValue;
1011         }
1012         try {
1013             return Level.parse(val.trim());
1014         } catch (Exception ex) {
1015             return defaultValue;
1016         }
1017     }
1018 
1019     // Package private method to get a filter property.
1020     // We return an instance of the class named by the "name"
1021     // property. If the property is not defined or has problems
1022     // we return the defaultValue.
1023     Filter getFilterProperty(String name, Filter defaultValue) {
1024         String val = getProperty(name);
1025         try {
1026             if (val != null) {
1027                 Class clz = ClassLoader.getSystemClassLoader().loadClass(val);
1028                 return (Filter) clz.newInstance();
1029             }
1030         } catch (Exception ex) {
1031             // We got one of a variety of exceptions in creating the
1032             // class or creating an instance.
1033             // Drop through.
1034         }
1035         // We got an exception.  Return the defaultValue.
1036         return defaultValue;
1037     }
1038 
1039 
1040     // Package private method to get a formatter property.
1041     // We return an instance of the class named by the "name"
1042     // property. If the property is not defined or has problems
1043     // we return the defaultValue.
1044     Formatter getFormatterProperty(String name, Formatter defaultValue) {
1045         String val = getProperty(name);
1046         try {
1047             if (val != null) {
1048                 Class clz = ClassLoader.getSystemClassLoader().loadClass(val);
1049                 return (Formatter) clz.newInstance();
1050             }
1051         } catch (Exception ex) {
1052             // We got one of a variety of exceptions in creating the
1053             // class or creating an instance.
1054             // Drop through.
1055         }
1056         // We got an exception.  Return the defaultValue.
1057         return defaultValue;
1058     }
1059 
1060     // Private method to load the global handlers.
1061     // We do the real work lazily, when the global handlers
1062     // are first used.
1063     private synchronized void initializeGlobalHandlers() {
1064         if (initializedGlobalHandlers) {
1065             return;
1066         }
1067 
1068         initializedGlobalHandlers = true;


1146         public void addHandler(Handler h) {
1147             initializeGlobalHandlers();
1148             super.addHandler(h);
1149         }
1150 
1151         public void removeHandler(Handler h) {
1152             initializeGlobalHandlers();
1153             super.removeHandler(h);
1154         }
1155 
1156         public Handler[] getHandlers() {
1157             initializeGlobalHandlers();
1158             return super.getHandlers();
1159         }
1160     }
1161 
1162 
1163     // Private method to be called when the configuration has
1164     // changed to apply any level settings to any pre-existing loggers.
1165     synchronized private void setLevelsOnExistingLoggers() {
1166         Enumeration enum_ = props.propertyNames();
1167         while (enum_.hasMoreElements()) {
1168             String key = (String)enum_.nextElement();
1169             if (!key.endsWith(".level")) {
1170                 // Not a level definition.
1171                 continue;
1172             }
1173             int ix = key.length() - 6;
1174             String name = key.substring(0, ix);
1175             Level level = getLevelProperty(key, null);
1176             if (level == null) {
1177                 System.err.println("Bad level value for property: " + key);
1178                 continue;
1179             }
1180             Logger l = getLogger(name);
1181             if (l == null) {
1182                 continue;
1183             }
1184             l.setLevel(level);
1185         }
1186     }




 162     private Logger rootLogger;
 163 
 164     // Have we done the primordial reading of the configuration file?
 165     // (Must be done after a suitable amount of java.lang.System
 166     // initialization has been done)
 167     private volatile boolean readPrimordialConfiguration;
 168     // Have we initialized global (root) handlers yet?
 169     // This gets set to false in readConfiguration
 170     private boolean initializedGlobalHandlers = true;
 171     // True if JVM death is imminent and the exit hook has been called.
 172     private boolean deathImminent;
 173 
 174     static {
 175         AccessController.doPrivileged(new PrivilegedAction<Object>() {
 176                 public Object run() {
 177                     String cname = null;
 178                     try {
 179                         cname = System.getProperty("java.util.logging.manager");
 180                         if (cname != null) {
 181                             try {
 182                                 Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname);
 183                                 manager = (LogManager) clz.newInstance();
 184                             } catch (ClassNotFoundException ex) {
 185                                 Class<?> clz = Thread.currentThread().getContextClassLoader().loadClass(cname);
 186                                 manager = (LogManager) clz.newInstance();
 187                             }
 188                         }
 189                     } catch (Exception ex) {
 190                         System.err.println("Could not load Logmanager \"" + cname + "\"");
 191                         ex.printStackTrace();
 192                     }
 193                     if (manager == null) {
 194                         manager = new LogManager();
 195                     }
 196 
 197                     // Create and retain Logger for the root of the namespace.
 198                     manager.rootLogger = manager.new RootLogger();
 199                     manager.addLogger(manager.rootLogger);
 200 
 201                     // Adding the global Logger. Doing so in the Logger.<clinit>
 202                     // would deadlock with the LogManager.<clinit>.
 203                     Logger.getGlobal().setLogManager(manager);
 204                     manager.addLogger(Logger.getGlobal());
 205 
 206                     // We don't call readConfiguration() here, as we may be running
 207                     // very early in the JVM startup sequence.  Instead readConfiguration
 208                     // will be called lazily in getLogManager().
 209                     return null;
 210                 }
 211             });
 212     }
 213 
 214 
 215     // This private class is used as a shutdown hook.
 216     // It does a "reset" to close all open handlers.
 217     private class Cleaner extends Thread {
 218 
 219         private Cleaner() {
 220             /* Set context class loader to null in order to avoid
 221              * keeping a strong reference to an application classloader.
 222              */
 223             this.setContextClassLoader(null);
 224         }


 398 
 399     // Add new per logger handlers.
 400     // We need to raise privilege here. All our decisions will
 401     // be made based on the logging configuration, which can
 402     // only be modified by trusted code.
 403     private void loadLoggerHandlers(final Logger logger, final String name,
 404                                     final String handlersPropertyName) {
 405         AccessController.doPrivileged(new PrivilegedAction<Object>() {
 406             public Object run() {
 407                 if (logger != rootLogger) {
 408                     boolean useParent = getBooleanProperty(name + ".useParentHandlers", true);
 409                     if (!useParent) {
 410                         logger.setUseParentHandlers(false);
 411                     }
 412                 }
 413 
 414                 String names[] = parseClassNames(handlersPropertyName);
 415                 for (int i = 0; i < names.length; i++) {
 416                     String word = names[i];
 417                     try {
 418                         Class<?>   clz = ClassLoader.getSystemClassLoader().loadClass(word);
 419                         Handler hdl = (Handler) clz.newInstance();
 420                         try {
 421                             // Check if there is a property defining the
 422                             // this handler's level.
 423                             String levs = getProperty(word + ".level");
 424                             if (levs != null) {
 425                                 hdl.setLevel(Level.parse(levs));
 426                             }
 427                         } catch (Exception ex) {
 428                             System.err.println("Can't set level for " + word);
 429                             // Probably a bad level. Drop through.
 430                         }
 431                         // Add this Handler to the logger
 432                         logger.addHandler(hdl);
 433                     } catch (Exception ex) {
 434                         System.err.println("Can't load log handler \"" + word + "\"");
 435                         System.err.println("" + ex);
 436                         ex.printStackTrace();
 437                     }
 438                 }


 765      * Any log level definitions in the new configuration file will be
 766      * applied using Logger.setLevel(), if the target Logger exists.
 767      * <p>
 768      * A PropertyChangeEvent will be fired after the properties are read.
 769      *
 770      * @exception  SecurityException  if a security manager exists and if
 771      *             the caller does not have LoggingPermission("control").
 772      * @exception  IOException if there are IO problems reading the configuration.
 773      */
 774     public void readConfiguration() throws IOException, SecurityException {
 775         checkAccess();
 776 
 777         // if a configuration class is specified, load it and use it.
 778         String cname = System.getProperty("java.util.logging.config.class");
 779         if (cname != null) {
 780             try {
 781                 // Instantiate the named class.  It is its constructor's
 782                 // responsibility to initialize the logging configuration, by
 783                 // calling readConfiguration(InputStream) with a suitable stream.
 784                 try {
 785                     Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname);
 786                     clz.newInstance();
 787                     return;
 788                 } catch (ClassNotFoundException ex) {
 789                     Class<?> clz = Thread.currentThread().getContextClassLoader().loadClass(cname);
 790                     clz.newInstance();
 791                     return;
 792                 }
 793             } catch (Exception ex) {
 794                 System.err.println("Logging configuration class \"" + cname + "\" failed");
 795                 System.err.println("" + ex);
 796                 // keep going and useful config file.
 797             }
 798         }
 799 
 800         String fname = System.getProperty("java.util.logging.config.file");
 801         if (fname == null) {
 802             fname = System.getProperty("java.home");
 803             if (fname == null) {
 804                 throw new Error("Can't find java.home ??");
 805             }
 806             File f = new File(fname, "lib");
 807             f = new File(f, "logging.properties");
 808             fname = f.getCanonicalPath();
 809         }


 820 
 821     /**
 822      * Reset the logging configuration.
 823      * <p>
 824      * For all named loggers, the reset operation removes and closes
 825      * all Handlers and (except for the root logger) sets the level
 826      * to null.  The root logger's level is set to Level.INFO.
 827      *
 828      * @exception  SecurityException  if a security manager exists and if
 829      *             the caller does not have LoggingPermission("control").
 830      */
 831 
 832     public void reset() throws SecurityException {
 833         checkAccess();
 834         synchronized (this) {
 835             props = new Properties();
 836             // Since we are doing a reset we no longer want to initialize
 837             // the global handlers, if they haven't been initialized yet.
 838             initializedGlobalHandlers = true;
 839         }
 840         Enumeration<String> enum_ = getLoggerNames();
 841         while (enum_.hasMoreElements()) {
 842             String name = enum_.nextElement();
 843             resetLogger(name);
 844         }
 845     }
 846 
 847 
 848     // Private method to reset an individual target logger.
 849     private void resetLogger(String name) {
 850         Logger logger = getLogger(name);
 851         if (logger == null) {
 852             return;
 853         }
 854         // Close all the Logger's handlers.
 855         Handler[] targets = logger.getHandlers();
 856         for (int i = 0; i < targets.length; i++) {
 857             Handler h = targets[i];
 858             logger.removeHandler(h);
 859             try {
 860                 h.close();
 861             } catch (Exception ex) {
 862                 // Problems closing a handler?  Keep going...


 909      * Any log level definitions in the new configuration file will be
 910      * applied using Logger.setLevel(), if the target Logger exists.
 911      *
 912      * @param ins       stream to read properties from
 913      * @exception  SecurityException  if a security manager exists and if
 914      *             the caller does not have LoggingPermission("control").
 915      * @exception  IOException if there are problems reading from the stream.
 916      */
 917     public void readConfiguration(InputStream ins) throws IOException, SecurityException {
 918         checkAccess();
 919         reset();
 920 
 921         // Load the properties
 922         props.load(ins);
 923         // Instantiate new configuration objects.
 924         String names[] = parseClassNames("config");
 925 
 926         for (int i = 0; i < names.length; i++) {
 927             String word = names[i];
 928             try {
 929                 Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
 930                 clz.newInstance();
 931             } catch (Exception ex) {
 932                 System.err.println("Can't load config class \"" + word + "\"");
 933                 System.err.println("" + ex);
 934                 // ex.printStackTrace();
 935             }
 936         }
 937 
 938         // Set levels on any pre-existing loggers, based on the new properties.
 939         setLevelsOnExistingLoggers();
 940 
 941         // Notify any interested parties that our properties have changed.
 942         changes.firePropertyChange(null, null, null);
 943 
 944         // Note that we need to reinitialize global handles when
 945         // they are first referenced.
 946         synchronized (this) {
 947             initializedGlobalHandlers = false;
 948         }
 949     }


1007     Level getLevelProperty(String name, Level defaultValue) {
1008         String val = getProperty(name);
1009         if (val == null) {
1010             return defaultValue;
1011         }
1012         try {
1013             return Level.parse(val.trim());
1014         } catch (Exception ex) {
1015             return defaultValue;
1016         }
1017     }
1018 
1019     // Package private method to get a filter property.
1020     // We return an instance of the class named by the "name"
1021     // property. If the property is not defined or has problems
1022     // we return the defaultValue.
1023     Filter getFilterProperty(String name, Filter defaultValue) {
1024         String val = getProperty(name);
1025         try {
1026             if (val != null) {
1027                 Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
1028                 return (Filter) clz.newInstance();
1029             }
1030         } catch (Exception ex) {
1031             // We got one of a variety of exceptions in creating the
1032             // class or creating an instance.
1033             // Drop through.
1034         }
1035         // We got an exception.  Return the defaultValue.
1036         return defaultValue;
1037     }
1038 
1039 
1040     // Package private method to get a formatter property.
1041     // We return an instance of the class named by the "name"
1042     // property. If the property is not defined or has problems
1043     // we return the defaultValue.
1044     Formatter getFormatterProperty(String name, Formatter defaultValue) {
1045         String val = getProperty(name);
1046         try {
1047             if (val != null) {
1048                 Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
1049                 return (Formatter) clz.newInstance();
1050             }
1051         } catch (Exception ex) {
1052             // We got one of a variety of exceptions in creating the
1053             // class or creating an instance.
1054             // Drop through.
1055         }
1056         // We got an exception.  Return the defaultValue.
1057         return defaultValue;
1058     }
1059 
1060     // Private method to load the global handlers.
1061     // We do the real work lazily, when the global handlers
1062     // are first used.
1063     private synchronized void initializeGlobalHandlers() {
1064         if (initializedGlobalHandlers) {
1065             return;
1066         }
1067 
1068         initializedGlobalHandlers = true;


1146         public void addHandler(Handler h) {
1147             initializeGlobalHandlers();
1148             super.addHandler(h);
1149         }
1150 
1151         public void removeHandler(Handler h) {
1152             initializeGlobalHandlers();
1153             super.removeHandler(h);
1154         }
1155 
1156         public Handler[] getHandlers() {
1157             initializeGlobalHandlers();
1158             return super.getHandlers();
1159         }
1160     }
1161 
1162 
1163     // Private method to be called when the configuration has
1164     // changed to apply any level settings to any pre-existing loggers.
1165     synchronized private void setLevelsOnExistingLoggers() {
1166         Enumeration<?> enum_ = props.propertyNames();
1167         while (enum_.hasMoreElements()) {
1168             String key = (String)enum_.nextElement();
1169             if (!key.endsWith(".level")) {
1170                 // Not a level definition.
1171                 continue;
1172             }
1173             int ix = key.length() - 6;
1174             String name = key.substring(0, ix);
1175             Level level = getLevelProperty(key, null);
1176             if (level == null) {
1177                 System.err.println("Bad level value for property: " + key);
1178                 continue;
1179             }
1180             Logger l = getLogger(name);
1181             if (l == null) {
1182                 continue;
1183             }
1184             l.setLevel(level);
1185         }
1186     }