diff options
Diffstat (limited to 'java/openjdk6/files/icedtea/security/20130201/6664509.patch')
-rw-r--r-- | java/openjdk6/files/icedtea/security/20130201/6664509.patch | 1322 |
1 files changed, 0 insertions, 1322 deletions
diff --git a/java/openjdk6/files/icedtea/security/20130201/6664509.patch b/java/openjdk6/files/icedtea/security/20130201/6664509.patch deleted file mode 100644 index 8d8f3191d014..000000000000 --- a/java/openjdk6/files/icedtea/security/20130201/6664509.patch +++ /dev/null @@ -1,1322 +0,0 @@ -# HG changeset patch -# User coffeys -# Date 1355432912 0 -# Node ID eed3ef0116a18e006c4e062b3c8d6d5a5e503a43 -# Parent bedb05bba7fc681e34f9c3ce03dc2daa4ec2ce28 -6664509: Add logging context -6664528: Find log level matching its name or value given at construction time -Reviewed-by: mchung - -diff --git a/src/share/classes/java/util/logging/Level.java b/src/share/classes/java/util/logging/Level.java ---- jdk/src/share/classes/java/util/logging/Level.java -+++ jdk/src/share/classes/java/util/logging/Level.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -24,6 +24,10 @@ - */ - - package java.util.logging; -+import java.util.ArrayList; -+import java.util.HashMap; -+import java.util.List; -+import java.util.Map; - import java.util.ResourceBundle; - - /** -@@ -59,7 +63,6 @@ import java.util.ResourceBundle; - */ - - public class Level implements java.io.Serializable { -- private static java.util.ArrayList<Level> known = new java.util.ArrayList<Level>(); - private static String defaultBundle = "sun.util.logging.resources.logging"; - - /** -@@ -76,6 +79,9 @@ public class Level implements java.io.Se - * @serial The resource bundle name to be used in localizing the level name. - */ - private final String resourceBundleName; -+ -+ // localized level name -+ private String localizedLevelName; - - /** - * OFF is a special level that can be used to turn off logging. -@@ -202,9 +208,8 @@ public class Level implements java.io.Se - this.name = name; - this.value = value; - this.resourceBundleName = resourceBundleName; -- synchronized (Level.class) { -- known.add(this); -- } -+ this.localizedLevelName = resourceBundleName == null ? name : null; -+ KnownLevel.add(this); - } - - /** -@@ -236,12 +241,76 @@ public class Level implements java.io.Se - * @return localized name - */ - public String getLocalizedName() { -+ return getLocalizedLevelName(); -+ } -+ -+ // package-private getLevelName() is used by the implementation -+ // instead of getName() to avoid calling the subclass's version -+ final String getLevelName() { -+ return this.name; -+ } -+ -+ final synchronized String getLocalizedLevelName() { -+ if (localizedLevelName != null) { -+ return localizedLevelName; -+ } -+ - try { - ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName); -- return rb.getString(name); -+ localizedLevelName = rb.getString(name); - } catch (Exception ex) { -- return name; -+ localizedLevelName = name; - } -+ return localizedLevelName; -+ } -+ -+ // Returns a mirrored Level object that matches the given name as -+ // specified in the Level.parse method. Returns null if not found. -+ // -+ // It returns the same Level object as the one returned by Level.parse -+ // method if the given name is a non-localized name or integer. -+ // -+ // If the name is a localized name, findLevel and parse method may -+ // return a different level value if there is a custom Level subclass -+ // that overrides Level.getLocalizedName() to return a different string -+ // than what's returned by the default implementation. -+ // -+ static Level findLevel(String name) { -+ if (name == null) { -+ throw new NullPointerException(); -+ } -+ -+ KnownLevel level; -+ -+ // Look for a known Level with the given non-localized name. -+ level = KnownLevel.findByName(name); -+ if (level != null) { -+ return level.mirroredLevel; -+ } -+ -+ // Now, check if the given name is an integer. If so, -+ // first look for a Level with the given value and then -+ // if necessary create one. -+ try { -+ int x = Integer.parseInt(name); -+ level = KnownLevel.findByValue(x); -+ if (level == null) { -+ // add new Level -+ Level levelObject = new Level(name, x); -+ level = KnownLevel.findByValue(x); -+ } -+ return level.mirroredLevel; -+ } catch (NumberFormatException ex) { -+ // Not an integer. -+ // Drop through. -+ } -+ -+ level = KnownLevel.findByLocalizedLevelName(name); -+ if (level != null) { -+ return level.mirroredLevel; -+ } -+ -+ return null; - } - - /** -@@ -266,21 +335,15 @@ public class Level implements java.io.Se - // Serialization magic to prevent "doppelgangers". - // This is a performance optimization. - private Object readResolve() { -- synchronized (Level.class) { -- for (int i = 0; i < known.size(); i++) { -- Level other = known.get(i); -- if (this.name.equals(other.name) && this.value == other.value -- && (this.resourceBundleName == other.resourceBundleName || -- (this.resourceBundleName != null && -- this.resourceBundleName.equals(other.resourceBundleName)))) { -- return other; -- } -- } -- // Woops. Whoever sent us this object knows -- // about a new log level. Add it to our list. -- known.add(this); -- return this; -+ KnownLevel o = KnownLevel.matches(this); -+ if (o != null) { -+ return o.levelObject; - } -+ -+ // Woops. Whoever sent us this object knows -+ // about a new log level. Add it to our list. -+ Level level = new Level(this.name, this.value, this.resourceBundleName); -+ return level; - } - - /** -@@ -294,6 +357,7 @@ public class Level implements java.io.Se - * <li> "SEVERE" - * <li> "1000" - * </ul> -+ * - * @param name string to be parsed - * @throws NullPointerException if the name is null - * @throws IllegalArgumentException if the value is not valid. -@@ -313,12 +377,12 @@ public class Level implements java.io.Se - // Check that name is not null. - name.length(); - -+ KnownLevel level; -+ - // Look for a known Level with the given non-localized name. -- for (int i = 0; i < known.size(); i++) { -- Level l = known.get(i); -- if (name.equals(l.name)) { -- return l; -- } -+ level = KnownLevel.findByName(name); -+ if (level != null) { -+ return level.levelObject; - } - - // Now, check if the given name is an integer. If so, -@@ -326,27 +390,23 @@ public class Level implements java.io.Se - // if necessary create one. - try { - int x = Integer.parseInt(name); -- for (int i = 0; i < known.size(); i++) { -- Level l = known.get(i); -- if (l.value == x) { -- return l; -- } -+ level = KnownLevel.findByValue(x); -+ if (level == null) { -+ // add new Level -+ Level levelObject = new Level(name, x); -+ level = KnownLevel.findByValue(x); - } -- // Create a new Level. -- return new Level(name, x); -+ return level.levelObject; - } catch (NumberFormatException ex) { - // Not an integer. - // Drop through. - } -- -- // Finally, look for a known level with the given localized name, -+ // Finally, look for a known level with the given localized name, - // in the current default locale. - // This is relatively expensive, but not excessively so. -- for (int i = 0; i < known.size(); i++) { -- Level l = known.get(i); -- if (name.equals(l.getLocalizedName())) { -- return l; -- } -+ level = KnownLevel.findByLocalizedName(name); -+ if (level != null) { -+ return level.levelObject; - } - - // OK, we've tried everything and failed -@@ -373,4 +433,125 @@ public class Level implements java.io.Se - public int hashCode() { - return this.value; - } -+ -+ // KnownLevel class maintains the global list of all known levels. -+ // The API allows multiple custom Level instances of the same name/value -+ // be created. This class provides convenient methods to find a level -+ // by a given name, by a given value, or by a given localized name. -+ // -+ // KnownLevel wraps the following Level objects: -+ // 1. levelObject: standard Level object or custom Level object -+ // 2. mirroredLevel: Level object representing the level specified in the -+ // logging configuration. -+ // -+ // Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods -+ // are non-final but the name and resource bundle name are parameters to -+ // the Level constructor. Use the mirroredLevel object instead of the -+ // levelObject to prevent the logging framework to execute foreign code -+ // implemented by untrusted Level subclass. -+ // -+ // Implementation Notes: -+ // If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods -+ // were final, the following KnownLevel implementation can be removed. -+ // Future API change should take this into consideration. -+ static final class KnownLevel { -+ private static Map<String, List<KnownLevel>> nameToLevels = -+ new HashMap<String, List<KnownLevel>>(); -+ private static Map<Integer, List<KnownLevel>> intToLevels = -+ new HashMap<Integer, List<KnownLevel>>(); -+ final Level levelObject; // instance of Level class or Level subclass -+ final Level mirroredLevel; // instance of Level class -+ KnownLevel(Level l) { -+ this.levelObject = l; -+ if (l.getClass() == Level.class) { -+ this.mirroredLevel = l; -+ } else { -+ this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName); -+ } -+ } -+ -+ static synchronized void add(Level l) { -+ // the mirroredLevel object is always added to the list -+ // before the custom Level instance -+ KnownLevel o = new KnownLevel(l); -+ List<KnownLevel> list = nameToLevels.get(l.name); -+ if (list == null) { -+ list = new ArrayList<KnownLevel>(); -+ nameToLevels.put(l.name, list); -+ } -+ list.add(o); -+ -+ list = intToLevels.get(l.value); -+ if (list == null) { -+ list = new ArrayList<KnownLevel>(); -+ intToLevels.put(l.value, list); -+ } -+ list.add(o); -+ } -+ -+ // Returns a KnownLevel with the given non-localized name. -+ static synchronized KnownLevel findByName(String name) { -+ List<KnownLevel> list = nameToLevels.get(name); -+ if (list != null) { -+ return list.get(0); -+ } -+ return null; -+ } -+ -+ // Returns a KnownLevel with the given value. -+ static synchronized KnownLevel findByValue(int value) { -+ List<KnownLevel> list = intToLevels.get(value); -+ if (list != null) { -+ return list.get(0); -+ } -+ return null; -+ } -+ -+ // Returns a KnownLevel with the given localized name matching -+ // by calling the Level.getLocalizedLevelName() method (i.e. found -+ // from the resourceBundle associated with the Level object). -+ // This method does not call Level.getLocalizedName() that may -+ // be overridden in a subclass implementation -+ static synchronized KnownLevel findByLocalizedLevelName(String name) { -+ for (List<KnownLevel> levels : nameToLevels.values()) { -+ for (KnownLevel l : levels) { -+ String lname = l.levelObject.getLocalizedLevelName(); -+ if (name.equals(lname)) { -+ return l; -+ } -+ } -+ } -+ return null; -+ } -+ -+ // Returns a KnownLevel with the given localized name matching -+ // by calling the Level.getLocalizedName() method -+ static synchronized KnownLevel findByLocalizedName(String name) { -+ for (List<KnownLevel> levels : nameToLevels.values()) { -+ for (KnownLevel l : levels) { -+ String lname = l.levelObject.getLocalizedName(); -+ if (name.equals(lname)) { -+ return l; -+ } -+ } -+ } -+ return null; -+ } -+ -+ static synchronized KnownLevel matches(Level l) { -+ List<KnownLevel> list = nameToLevels.get(l.name); -+ if (list != null) { -+ for (KnownLevel level : list) { -+ Level other = level.mirroredLevel; -+ if (l.value == other.value && -+ (l.resourceBundleName == other.resourceBundleName || -+ (l.resourceBundleName != null && -+ l.resourceBundleName.equals(other.resourceBundleName)))) { -+ return level; -+ } -+ } -+ } -+ return null; -+ } -+ } - } -diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java ---- jdk/src/share/classes/java/util/logging/LogManager.java -+++ jdk/src/share/classes/java/util/logging/LogManager.java -@@ -34,6 +34,8 @@ import java.beans.PropertyChangeListener - import java.beans.PropertyChangeListener; - import java.beans.PropertyChangeSupport; - import java.net.URL; -+import sun.misc.JavaAWTAccess; -+import sun.misc.SharedSecrets; - import sun.security.action.GetPropertyAction; - - /** -@@ -155,11 +157,9 @@ public class LogManager { - = new PropertyChangeSupport(LogManager.class); - private final static Level defaultLevel = Level.INFO; - -- // Table of named Loggers that maps names to Loggers. -- private Hashtable<String,LoggerWeakRef> namedLoggers = -- new Hashtable<String,LoggerWeakRef>(); -- // Tree of named Loggers -- private LogNode root = new LogNode(null); -+ // LoggerContext for system loggers and user loggers -+ private final LoggerContext systemContext = new SystemLoggerContext(); -+ private final LoggerContext userContext = new UserLoggerContext(); - private Logger rootLogger; - - // Have we done the primordial reading of the configuration file? -@@ -197,12 +197,13 @@ public class LogManager { - - // Create and retain Logger for the root of the namespace. - manager.rootLogger = manager.new RootLogger(); -- manager.addLogger(manager.rootLogger); -+ manager.systemContext.addLogger(manager.rootLogger); -+ manager.userContext.addLogger(manager.rootLogger); - - // Adding the global Logger. Doing so in the Logger.<clinit> - // would deadlock with the LogManager.<clinit>. - Logger.global.setLogManager(manager); -- manager.addLogger(Logger.global); -+ manager.systemContext.addLogger(Logger.global); - - // We don't call readConfiguration() here, as we may be running - // very early in the JVM startup sequence. Instead readConfiguration -@@ -273,8 +274,8 @@ public class LogManager { - } - readPrimordialConfiguration = true; - try { -- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { -- public Object run() throws Exception { -+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { -+ public Void run() throws Exception { - readConfiguration(); - return null; - } -@@ -326,6 +327,296 @@ public class LogManager { - changes.removePropertyChangeListener(l); - } - -+ // Returns the LoggerContext for the user code (i.e. application or AppContext). -+ // Loggers are isolated from each AppContext. -+ LoggerContext getUserContext() { -+ LoggerContext context = null; -+ -+ SecurityManager sm = System.getSecurityManager(); -+ JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess(); -+ if (sm != null && javaAwtAccess != null) { -+ synchronized (javaAwtAccess) { -+ // AppContext.getAppContext() returns the system AppContext if called -+ // from a system thread but Logger.getLogger might be called from -+ // an applet code. Instead, find the AppContext of the applet code -+ // from the execution stack. -+ Object ecx = javaAwtAccess.getExecutionContext(); -+ if (ecx == null) { -+ // fall back to AppContext.getAppContext() -+ ecx = javaAwtAccess.getContext(); -+ } -+ context = (LoggerContext) javaAwtAccess.get(ecx, LoggerContext.class); -+ if (context == null) { -+ if (javaAwtAccess.isMainAppContext()) { -+ context = userContext; -+ } else { -+ context = new UserLoggerContext(); -+ context.addLogger(manager.rootLogger); -+ } -+ javaAwtAccess.put(ecx, LoggerContext.class, context); -+ } -+ } -+ } else { -+ context = userContext; -+ } -+ return context; -+ } -+ -+ LoggerContext getSystemContext() { -+ return systemContext; -+ } -+ -+ private List<LoggerContext> contexts() { -+ List<LoggerContext> cxs = new ArrayList<LoggerContext>(); -+ cxs.add(systemContext); -+ cxs.add(getUserContext()); -+ return cxs; -+ } -+ -+ static class LoggerContext { -+ // Table of named Loggers that maps names to Loggers. -+ -+ private final Hashtable<String, LoggerWeakRef> namedLoggers = -+ new Hashtable<String, LoggerWeakRef>(); -+ // Tree of named Loggers -+ private final LogNode root; -+ -+ private LoggerContext() { -+ this.root = new LogNode(null, this); -+ } -+ -+ synchronized Logger findLogger(String name) { -+ LoggerWeakRef ref = namedLoggers.get(name); -+ if (ref == null) { -+ return null; -+ } -+ Logger logger = ref.get(); -+ if (logger == null) { -+ // Hashtable holds stale weak reference -+ // to a logger which has been GC-ed. -+ removeLogger(name); -+ } -+ return logger; -+ } -+ -+ synchronized boolean addLogger(Logger logger) { -+ final String name = logger.getName(); -+ if (name == null) { -+ throw new NullPointerException(); -+ } -+ -+ // cleanup some Loggers that have been GC'ed -+ manager.drainLoggerRefQueueBounded(); -+ -+ LoggerWeakRef ref = namedLoggers.get(name); -+ if (ref != null) { -+ if (ref.get() == null) { -+ // It's possible that the Logger was GC'ed after the -+ // drainLoggerRefQueueBounded() call above so allow -+ // a new one to be registered. -+ removeLogger(name); -+ } else { -+ // We already have a registered logger with the given name. -+ return false; -+ } -+ } -+ -+ // We're adding a new logger. -+ // Note that we are creating a weak reference here. -+ ref = manager.new LoggerWeakRef(logger); -+ namedLoggers.put(name, ref); -+ -+ // Apply any initial level defined for the new logger. -+ Level level = manager.getLevelProperty(name + ".level", null); -+ if (level != null) { -+ doSetLevel(logger, level); -+ } -+ -+ // Do we have a per logger handler too? -+ // Note: this will add a 200ms penalty -+ manager.loadLoggerHandlers(logger, name, name + ".handlers"); -+ processParentHandlers(logger, name); -+ -+ // Find the new node and its parent. -+ LogNode node = getNode(name); -+ node.loggerRef = ref; -+ Logger parent = null; -+ LogNode nodep = node.parent; -+ while (nodep != null) { -+ LoggerWeakRef nodeRef = nodep.loggerRef; -+ if (nodeRef != null) { -+ parent = nodeRef.get(); -+ if (parent != null) { -+ break; -+ } -+ } -+ nodep = nodep.parent; -+ } -+ -+ if (parent != null) { -+ doSetParent(logger, parent); -+ } -+ // Walk over the children and tell them we are their new parent. -+ node.walkAndSetParent(logger); -+ // new LogNode is ready so tell the LoggerWeakRef about it -+ ref.setNode(node); -+ return true; -+ } -+ -+ void removeLogger(String name) { -+ namedLoggers.remove(name); -+ } -+ -+ synchronized Enumeration<String> getLoggerNames() { -+ return namedLoggers.keys(); -+ } -+ -+ Logger demandLogger(String name) { -+ return demandLogger(name, null); -+ } -+ -+ // Find or create a specified logger instance. If a logger has -+ // already been created with the given name it is returned. -+ // Otherwise a new logger instance is created and registered -+ // in the LogManager global namespace. -+ // This method will always return a non-null Logger object. -+ // Synchronization is not required here. All synchronization for -+ // adding a new Logger object is handled by addLogger(). -+ Logger demandLogger(String name, String resourceBundleName) { -+ Logger result = findLogger(name); -+ if (result == null) { -+ // only allocate the new logger once -+ Logger newLogger = new Logger(name, resourceBundleName); -+ do { -+ if (addLogger(newLogger)) { -+ // We successfully added the new Logger that we -+ // created above so return it without refetching. -+ return newLogger; -+ } -+ -+ // We didn't add the new Logger that we created above -+ // because another thread added a Logger with the same -+ // name after our null check above and before our call -+ // to addLogger(). We have to refetch the Logger because -+ // addLogger() returns a boolean instead of the Logger -+ // reference itself. However, if the thread that created -+ // the other Logger is not holding a strong reference to -+ // the other Logger, then it is possible for the other -+ // Logger to be GC'ed after we saw it in addLogger() and -+ // before we can refetch it. If it has been GC'ed then -+ // we'll just loop around and try again. -+ result = findLogger(name); -+ } while (result == null); -+ } -+ return result; -+ } -+ -+ // If logger.getUseParentHandlers() returns 'true' and any of the logger's -+ // parents have levels or handlers defined, make sure they are instantiated. -+ private void processParentHandlers(Logger logger, String name) { -+ int ix = 1; -+ for (;;) { -+ int ix2 = name.indexOf(".", ix); -+ if (ix2 < 0) { -+ break; -+ } -+ String pname = name.substring(0, ix2); -+ -+ if (manager.getProperty(pname + ".level") != null -+ || manager.getProperty(pname + ".handlers") != null) { -+ // This pname has a level/handlers definition. -+ // Make sure it exists. -+ demandLogger(pname); -+ } -+ ix = ix2 + 1; -+ } -+ } -+ -+ // Gets a node in our tree of logger nodes. -+ // If necessary, create it. -+ LogNode getNode(String name) { -+ if (name == null || name.equals("")) { -+ return root; -+ } -+ LogNode node = root; -+ while (name.length() > 0) { -+ int ix = name.indexOf("."); -+ String head; -+ if (ix > 0) { -+ head = name.substring(0, ix); -+ name = name.substring(ix + 1); -+ } else { -+ head = name; -+ name = ""; -+ } -+ if (node.children == null) { -+ node.children = new HashMap<String, LogNode>(); -+ } -+ LogNode child = node.children.get(head); -+ if (child == null) { -+ child = new LogNode(node, this); -+ node.children.put(head, child); -+ } -+ node = child; -+ } -+ return node; -+ } -+ } -+ -+ static class SystemLoggerContext extends LoggerContext { -+ // Default resource bundle for all system loggers -+ -+ Logger demandLogger(String name) { -+ // default to use the system logger's resource bundle -+ return super.demandLogger(name, Logger.SYSTEM_LOGGER_RB_NAME); -+ } -+ } -+ -+ static class UserLoggerContext extends LoggerContext { -+ -+ /** -+ * Returns a Logger of the given name if there is one registered -+ * in this context. Otherwise, it will return the one registered -+ * in the system context if there is one. The returned Logger -+ * instance may be initialized with a different resourceBundleName. -+ * If no such logger exists, a new Logger instance will be created -+ * and registered in this context. -+ */ -+ Logger demandLogger(String name, String resourceBundleName) { -+ Logger result = findLogger(name); -+ if (result == null) { -+ // use the system logger if exists; or allocate a new logger. -+ // The system logger is added to the app logger context so that -+ // any child logger created in the app logger context can have -+ // a system logger as its parent if already exist. -+ Logger logger = manager.systemContext.findLogger(name); -+ Logger newLogger = -+ logger != null ? logger : new Logger(name, resourceBundleName); -+ do { -+ if (addLogger(newLogger)) { -+ // We successfully added the new Logger that we -+ // created above so return it without refetching. -+ return newLogger; -+ } -+ -+ // We didn't add the new Logger that we created above -+ // because another thread added a Logger with the same -+ // name after our null check above and before our call -+ // to addLogger(). We have to refetch the Logger because -+ // addLogger() returns a boolean instead of the Logger -+ // reference itself. However, if the thread that created -+ // the other Logger is not holding a strong reference to -+ // the other Logger, then it is possible for the other -+ // Logger to be GC'ed after we saw it in addLogger() and -+ // before we can refetch it. If it has been GC'ed then -+ // we'll just loop around and try again. -+ result = findLogger(name); -+ } while (result == null); -+ } -+ return result; -+ } -+ } -+ - // Package-level method. - // Find or create a specified logger instance. If a logger has - // already been created with the given name it is returned. -@@ -339,27 +630,6 @@ public class LogManager { - result = getLogger(name); - } - return result; -- } -- -- // If logger.getUseParentHandlers() returns 'true' and any of the logger's -- // parents have levels or handlers defined, make sure they are instantiated. -- private void processParentHandlers(Logger logger, String name) { -- int ix = 1; -- for (;;) { -- int ix2 = name.indexOf(".", ix); -- if (ix2 < 0) { -- break; -- } -- String pname = name.substring(0,ix2); -- -- if (getProperty(pname+".level") != null || -- getProperty(pname+".handlers") != null) { -- // This pname has a level/handlers definition. -- // Make sure it exists. -- demandLogger(pname); -- } -- ix = ix2+1; -- } - } - - // Add new per logger handlers. -@@ -383,16 +653,17 @@ public class LogManager { - try { - Class clz = ClassLoader.getSystemClassLoader().loadClass(word); - Handler hdl = (Handler) clz.newInstance(); -- try { -- // Check if there is a property defining the -- // this handler's level. -- String levs = getProperty(word + ".level"); -- if (levs != null) { -- hdl.setLevel(Level.parse(levs)); -+ // Check if there is a property defining the -+ // this handler's level. -+ String levs = getProperty(word + ".level"); -+ if (levs != null) { -+ Level l = Level.findLevel(levs); -+ if (l != null) { -+ hdl.setLevel(l); -+ } else { -+ // Probably a bad level. Drop through. -+ System.err.println("Can't set level for " + word); - } -- } catch (Exception ex) { -- System.err.println("Can't set level for " + word); -- // Probably a bad level. Drop through. - } - // Add this Handler to the logger - logger.addHandler(hdl); -@@ -448,7 +719,7 @@ public class LogManager { - if (node != null) { - // if we have a LogNode, then we were a named Logger - // so clear namedLoggers weak ref to us -- manager.namedLoggers.remove(name); -+ node.context.removeLogger(name); - name = null; // clear our ref to the Logger's name - - node.loggerRef = null; // clear LogNode's weak ref to us -@@ -544,67 +815,11 @@ public class LogManager { - if (name == null) { - throw new NullPointerException(); - } -- -- // cleanup some Loggers that have been GC'ed -- drainLoggerRefQueueBounded(); -- -- LoggerWeakRef ref = namedLoggers.get(name); -- if (ref != null) { -- if (ref.get() == null) { -- // It's possible that the Logger was GC'ed after the -- // drainLoggerRefQueueBounded() call above so allow -- // a new one to be registered. -- namedLoggers.remove(name); -- } else { -- // We already have a registered logger with the given name. -- return false; -- } -+ if (systemContext.findLogger(name) != null) { -+ return false; - } -- -- // We're adding a new logger. -- // Note that we are creating a weak reference here. -- ref = new LoggerWeakRef(logger); -- namedLoggers.put(name, ref); -- -- // Apply any initial level defined for the new logger. -- Level level = getLevelProperty(name+".level", null); -- if (level != null) { -- doSetLevel(logger, level); -- } -- -- // Do we have a per logger handler too? -- // Note: this will add a 200ms penalty -- loadLoggerHandlers(logger, name, name+".handlers"); -- processParentHandlers(logger, name); -- -- // Find the new node and its parent. -- LogNode node = findNode(name); -- node.loggerRef = ref; -- Logger parent = null; -- LogNode nodep = node.parent; -- while (nodep != null) { -- LoggerWeakRef nodeRef = nodep.loggerRef; -- if (nodeRef != null) { -- parent = nodeRef.get(); -- if (parent != null) { -- break; -- } -- } -- nodep = nodep.parent; -- } -- -- if (parent != null) { -- doSetParent(logger, parent); -- } -- // Walk over the children and tell them we are their new parent. -- node.walkAndSetParent(logger); -- -- // new LogNode is ready so tell the LoggerWeakRef about it -- ref.setNode(node); -- -- return true; -+ return getUserContext().addLogger(logger); - } -- - - // Private method to set a level on a logger. - // If necessary, we raise privilege before doing the call. -@@ -644,36 +859,6 @@ public class LogManager { - }}); - } - -- // Find a node in our tree of logger nodes. -- // If necessary, create it. -- private LogNode findNode(String name) { -- if (name == null || name.equals("")) { -- return root; -- } -- LogNode node = root; -- while (name.length() > 0) { -- int ix = name.indexOf("."); -- String head; -- if (ix > 0) { -- head = name.substring(0,ix); -- name = name.substring(ix+1); -- } else { -- head = name; -- name = ""; -- } -- if (node.children == null) { -- node.children = new HashMap<String,LogNode>(); -- } -- LogNode child = node.children.get(head); -- if (child == null) { -- child = new LogNode(node); -- node.children.put(head, child); -- } -- node = child; -- } -- return node; -- } -- - /** - * Method to find a named logger. - * <p> -@@ -689,18 +874,16 @@ public class LogManager { - * @param name name of the logger - * @return matching logger or null if none is found - */ -- public synchronized Logger getLogger(String name) { -- LoggerWeakRef ref = namedLoggers.get(name); -- if (ref == null) { -- return null; -- } -- Logger logger = ref.get(); -- if (logger == null) { -- // Hashtable holds stale weak reference -- // to a logger which has been GC-ed. -- namedLoggers.remove(name); -- } -- return logger; -+ public Logger getLogger(String name) { -+ // return the first logger added -+ // -+ // once a system logger is added in the system context, no one can -+ // adds a logger with the same name in the global context -+ // (see LogManager.addLogger). So if there is a logger in the global -+ // context with the same name as one in the system context, it must be -+ // added before the system logger was created. -+ Logger logger = getUserContext().findLogger(name); -+ return logger != null ? logger : systemContext.findLogger(name); - } - - /** -@@ -719,8 +902,12 @@ public class LogManager { - * <p> - * @return enumeration of logger name strings - */ -- public synchronized Enumeration<String> getLoggerNames() { -- return namedLoggers.keys(); -+ public Enumeration<String> getLoggerNames() { -+ // only return unique names -+ Set<String> names = -+ new HashSet<String>(Collections.list(systemContext.getLoggerNames())); -+ names.addAll(Collections.list(getUserContext().getLoggerNames())); -+ return Collections.enumeration(names); - } - - /** -@@ -805,20 +992,20 @@ public class LogManager { - // the global handlers, if they haven't been initialized yet. - initializedGlobalHandlers = true; - } -- Enumeration enum_ = getLoggerNames(); -- while (enum_.hasMoreElements()) { -- String name = (String)enum_.nextElement(); -- resetLogger(name); -+ for (LoggerContext cx : contexts()) { -+ Enumeration<String> enum_ = cx.getLoggerNames(); -+ while (enum_.hasMoreElements()) { -+ String name = enum_.nextElement(); -+ Logger logger = cx.findLogger(name); -+ if (logger != null) { -+ resetLogger(logger); -+ } -+ } - } - } - -- - // Private method to reset an individual target logger. -- private void resetLogger(String name) { -- Logger logger = getLogger(name); -- if (logger == null) { -- return; -- } -+ private void resetLogger(Logger logger) { - // Close all the Logger's handlers. - Handler[] targets = logger.getHandlers(); - for (int i = 0; i < targets.length; i++) { -@@ -830,6 +1017,7 @@ public class LogManager { - // Problems closing a handler? Keep going... - } - } -+ String name = logger.getName(); - if (name != null && name.equals("")) { - // This is the root logger. - logger.setLevel(defaultLevel); -@@ -977,11 +1165,8 @@ public class LogManager { - if (val == null) { - return defaultValue; - } -- try { -- return Level.parse(val.trim()); -- } catch (Exception ex) { -- return defaultValue; -- } -+ Level l = Level.findLevel(val.trim()); -+ return l != null ? l : defaultValue; - } - - // Package private method to get a filter property. -@@ -1072,9 +1257,11 @@ public class LogManager { - HashMap<String,LogNode> children; - LoggerWeakRef loggerRef; - LogNode parent; -+ final LoggerContext context; - -- LogNode(LogNode parent) { -+ LogNode(LogNode parent, LoggerContext context) { - this.parent = parent; -+ this.context = context; - } - - // Recursive method to walk the tree below a node and set -@@ -1133,7 +1320,7 @@ public class LogManager { - // Private method to be called when the configuration has - // changed to apply any level settings to any pre-existing loggers. - synchronized private void setLevelsOnExistingLoggers() { -- Enumeration enum_ = props.propertyNames(); -+ Enumeration<?> enum_ = props.propertyNames(); - while (enum_.hasMoreElements()) { - String key = (String)enum_.nextElement(); - if (!key.endsWith(".level")) { -@@ -1147,11 +1334,13 @@ public class LogManager { - System.err.println("Bad level value for property: " + key); - continue; - } -- Logger l = getLogger(name); -- if (l == null) { -- continue; -+ for (LoggerContext cx : contexts()) { -+ Logger l = cx.findLogger(name); -+ if (l == null) { -+ continue; -+ } -+ l.setLevel(level); - } -- l.setLevel(level); - } - } - -diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java ---- jdk/src/share/classes/java/util/logging/Logger.java -+++ jdk/src/share/classes/java/util/logging/Logger.java -@@ -29,6 +29,7 @@ import java.util.*; - import java.util.*; - import java.security.*; - import java.lang.ref.WeakReference; -+import java.util.logging.LogManager.LoggerContext; - - /** - * A Logger object is used to log messages for a specific -@@ -276,6 +277,26 @@ public class Logger { - } - } - -+ // Until all JDK code converted to call sun.util.logging.PlatformLogger -+ // (see 7054233), we need to determine if Logger.getLogger is to add -+ // a system logger or user logger. -+ // -+ // As an interim solution, if the immediate caller whose caller loader is -+ // null, we assume it's a system logger and add it to the system context. -+ private static LoggerContext getLoggerContext() { -+ LogManager manager = LogManager.getLogManager(); -+ SecurityManager sm = System.getSecurityManager(); -+ if (sm != null) { -+ // 0: Reflection 1: Logger.getLoggerContext 2: Logger.getLogger 3: caller -+ final int SKIP_FRAMES = 3; -+ Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES); -+ if (caller.getClassLoader() == null) { -+ return manager.getSystemContext(); -+ } -+ } -+ return manager.getUserContext(); -+ } -+ - /** - * Find or create a logger for a named subsystem. If a logger has - * already been created with the given name it is returned. Otherwise -@@ -304,8 +325,8 @@ public class Logger { - * @throws NullPointerException if the name is null. - */ - public static synchronized Logger getLogger(String name) { -- LogManager manager = LogManager.getLogManager(); -- return manager.demandLogger(name); -+ LoggerContext context = getLoggerContext(); -+ return context.demandLogger(name); - } - - /** -@@ -348,8 +369,8 @@ public class Logger { - * @throws NullPointerException if the name is null. - */ - public static synchronized Logger getLogger(String name, String resourceBundleName) { -- LogManager manager = LogManager.getLogManager(); -- Logger result = manager.demandLogger(name); -+ LoggerContext context = getLoggerContext(); -+ Logger result = context.demandLogger(name, resourceBundleName); - if (result.resourceBundleName == null) { - // Note: we may get a MissingResourceException here. - result.setupResourceInfo(resourceBundleName); -@@ -513,7 +534,7 @@ public class Logger { - private void doLog(LogRecord lr) { - lr.setLoggerName(name); - String ebname = getEffectiveResourceBundleName(); -- if (ebname != null) { -+ if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) { - lr.setResourceBundleName(ebname); - lr.setResourceBundle(findResourceBundle(ebname)); - } -@@ -1271,6 +1292,22 @@ public class Logger { - // May also return null if we can't find the resource bundle and - // there is no suitable previous cached value. - -+ static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging"; -+ -+ private static ResourceBundle findSystemResourceBundle(final Locale locale) { -+ // the resource bundle is in a restricted package -+ return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() { -+ public ResourceBundle run() { -+ try { -+ return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME, -+ locale); -+ } catch (MissingResourceException e) { -+ throw new InternalError(e.toString()); -+ } -+ } -+ }); -+ } -+ - private synchronized ResourceBundle findResourceBundle(String name) { - // Return a null bundle for a null name. - if (name == null) { -@@ -1282,6 +1319,13 @@ public class Logger { - // Normally we should hit on our simple one entry cache. - if (catalog != null && currentLocale == catalogLocale - && name == catalogName) { -+ return catalog; -+ } -+ -+ if (name.equals(SYSTEM_LOGGER_RB_NAME)) { -+ catalog = findSystemResourceBundle(currentLocale); -+ catalogName = name; -+ catalogLocale = currentLocale; - return catalog; - } - -diff --git a/src/share/classes/java/util/logging/Logging.java b/src/share/classes/java/util/logging/Logging.java ---- jdk/src/share/classes/java/util/logging/Logging.java -+++ jdk/src/share/classes/java/util/logging/Logging.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -34,15 +34,15 @@ import java.util.ArrayList; - * - * The <tt>LoggingMXBean</tt> interface provides a standard - * method for management access to the individual -- * java.util.Logger objects available at runtime. -+ * {@code Logger} objects available at runtime. - * - * @author Ron Mann - * @author Mandy Chung - * @since 1.5 - * - * @see javax.management -- * @see java.util.Logger -- * @see java.util.LogManager -+ * @see Logger -+ * @see LogManager - */ - class Logging implements LoggingMXBean { - -@@ -75,7 +75,7 @@ class Logging implements LoggingMXBean { - if (level == null) { - return EMPTY_STRING; - } else { -- return level.getName(); -+ return level.getLevelName(); - } - } - -@@ -94,7 +94,10 @@ class Logging implements LoggingMXBean { - Level level = null; - if (levelName != null) { - // parse will throw IAE if logLevel is invalid -- level = Level.parse(levelName); -+ level = Level.findLevel(levelName); -+ if (level == null) { -+ throw new IllegalArgumentException("Unknown level \"" + levelName + "\""); -+ } - } - - logger.setLevel(level); -diff --git a/src/share/classes/java/util/logging/SimpleFormatter.java b/src/share/classes/java/util/logging/SimpleFormatter.java ---- jdk/src/share/classes/java/util/logging/SimpleFormatter.java -+++ jdk/src/share/classes/java/util/logging/SimpleFormatter.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -83,7 +83,7 @@ public class SimpleFormatter extends For - } - sb.append(lineSeparator); - String message = formatMessage(record); -- sb.append(record.getLevel().getLocalizedName()); -+ sb.append(record.getLevel().getLocalizedLevelName()); - sb.append(": "); - sb.append(message); - sb.append(lineSeparator); -diff --git a/src/share/classes/sun/awt/AppContext.java b/src/share/classes/sun/awt/AppContext.java ---- jdk/src/share/classes/sun/awt/AppContext.java -+++ jdk/src/share/classes/sun/awt/AppContext.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -275,7 +275,7 @@ public final class AppContext { - if ((recent != null) && (recent.thread == currentThread)) { - appContext = recent.appContext; // Cache hit - } else { -- appContext = (AppContext)AccessController.doPrivileged( -+ appContext = (AppContext)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - // Get the current ThreadGroup, and look for it and its -@@ -319,19 +319,25 @@ public final class AppContext { - // Before we return the main "system" AppContext, check to - // see if there's an AWTSecurityManager installed. If so, - // allow it to choose the AppContext to return. -- SecurityManager securityManager = System.getSecurityManager(); -- if ((securityManager != null) && -- (securityManager instanceof AWTSecurityManager)) { -- AWTSecurityManager awtSecMgr = -- (AWTSecurityManager)securityManager; -- AppContext secAppContext = awtSecMgr.getAppContext(); -- if (secAppContext != null) { -- appContext = secAppContext; // Return what we're told -- } -+ AppContext secAppContext = getExecutionAppContext(); -+ if (secAppContext != null) { -+ appContext = secAppContext; // Return what we're told - } - } - - return appContext; -+ } -+ -+ private final static AppContext getExecutionAppContext() { -+ SecurityManager securityManager = System.getSecurityManager(); -+ if ((securityManager != null) && -+ (securityManager instanceof AWTSecurityManager)) -+ { -+ AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager; -+ AppContext secAppContext = awtSecMgr.getAppContext(); -+ return secAppContext; // Return what we're told -+ } -+ return null; - } - - private long DISPOSAL_TIMEOUT = 5000; // Default to 5-second timeout -@@ -786,6 +792,21 @@ public final class AppContext { - public boolean isMainAppContext() { - return (numAppContexts == 1); - } -+ public Object getContext() { -+ return getAppContext(); -+ } -+ public Object getExecutionContext() { -+ return getExecutionAppContext(); -+ } -+ public Object get(Object context, Object key) { -+ return ((AppContext)context).get(key); -+ } -+ public void put(Object context, Object key, Object value) { -+ ((AppContext)context).put(key, value); -+ } -+ public void remove(Object context, Object key) { -+ ((AppContext)context).remove(key); -+ } - }); - } - } -diff --git a/src/share/classes/sun/misc/JavaAWTAccess.java b/src/share/classes/sun/misc/JavaAWTAccess.java ---- jdk/src/share/classes/sun/misc/JavaAWTAccess.java -+++ jdk/src/share/classes/sun/misc/JavaAWTAccess.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -24,6 +24,14 @@ package sun.misc; - package sun.misc; - - public interface JavaAWTAccess { -+ public Object getContext(); -+ public Object getExecutionContext(); -+ -+ public Object get(Object context, Object key); -+ public void put(Object context, Object key, Object value); -+ public void remove(Object context, Object key); -+ -+ // convenience methods whose context is the object returned by getContext() - public Object get(Object key); - public void put(Object key, Object value); - public void remove(Object key); -diff --git a/src/share/lib/security/java.security b/src/share/lib/security/java.security ---- jdk/src/share/lib/security/java.security -+++ jdk/src/share/lib/security/java.security -@@ -129,7 +129,10 @@ system.scope=sun.security.provider.Ident - # been granted. - package.access=sun.,\ - com.sun.xml.internal.,\ -- com.sun.imageio. -+ com.sun.imageio.,\ -+ com.sun.istack.internal.,\ -+ com.sun.jmx.defaults.,\ -+ com.sun.jmx.remote.util. - - # - # List of comma-separated packages that start with or equal this string -@@ -143,7 +146,10 @@ package.access=sun.,\ - # - package.definition=sun.,\ - com.sun.xml.internal.,\ -- com.sun.imageio. -+ com.sun.imageio.,\ -+ com.sun.istack.internal.,\ -+ com.sun.jmx.defaults.,\ -+ com.sun.jmx.remote.util. - - # - # Determines whether this properties file can be appended to |