summaryrefslogtreecommitdiff
path: root/java/openjdk6/files/icedtea/security/20130201/6664509.patch
diff options
context:
space:
mode:
Diffstat (limited to 'java/openjdk6/files/icedtea/security/20130201/6664509.patch')
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/6664509.patch1322
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