[java-1.6.0-openjdk/f16] - removed patch8 revertTwoWrongSecurityPatches2013-02-06.patch - added patch8: 7201064.patch to be

jiri vanek jvanek at fedoraproject.org
Thu Feb 7 11:12:46 UTC 2013


commit 6a819e0167253d19f760d63069bb5ac77a85e459
Author: Jiri Vanek <jvanek at jvanek.redhat>
Date:   Thu Feb 7 12:13:19 2013 +0100

    - removed patch8 revertTwoWrongSecurityPatches2013-02-06.patch
    - added patch8:   7201064.patch to be reverted
    - added patch9:   8005615.patch to fix the 6664509.patch

 6664509.patch                                 | 1322 +++++++++++++++++++++++++
 7201064.patch                                 |  117 +++
 8005615.patch                                 |  933 +++++++++++++++++
 java-1.6.0-openjdk.spec                       |   19 +-
 revertTwoWrongSecurityPatches2013-02-06.patch |   19 -
 5 files changed, 2385 insertions(+), 25 deletions(-)
---
diff --git a/6664509.patch b/6664509.patch
new file mode 100644
index 0000000..32dc0f8
--- /dev/null
+++ b/6664509.patch
@@ -0,0 +1,1322 @@
+# 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
+--- openjdk/jdk/src/share/classes/java/util/logging/Level.java
++++ openjdk/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
+--- openjdk/jdk/src/share/classes/java/util/logging/LogManager.java
++++ openjdk/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
+--- openjdk/jdk/src/share/classes/java/util/logging/Logger.java
++++ openjdk/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
+--- openjdk/jdk/src/share/classes/java/util/logging/Logging.java
++++ openjdk/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
+--- openjdk/jdk/src/share/classes/java/util/logging/SimpleFormatter.java
++++ openjdk/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
+--- openjdk/jdk/src/share/classes/sun/awt/AppContext.java
++++ openjdk/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
+--- openjdk/jdk/src/share/classes/sun/misc/JavaAWTAccess.java
++++ openjdk/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
+--- openjdk/jdk/src/share/lib/security/java.security
++++ openjdk/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
diff --git a/7201064.patch b/7201064.patch
new file mode 100644
index 0000000..b04d47f
--- /dev/null
+++ b/7201064.patch
@@ -0,0 +1,117 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/java/awt/Dialog.java openjdk/jdk/src/share/classes/java/awt/Dialog.java
+--- openjdk.orig/jdk/src/share/classes/java/awt/Dialog.java	2013-02-01 21:38:34.033230540 +0000
++++ openjdk/jdk/src/share/classes/java/awt/Dialog.java	2013-02-01 21:40:04.270621182 +0000
+@@ -35,6 +35,7 @@
+ import javax.accessibility.*;
+ import sun.awt.AppContext;
+ import sun.awt.AWTAccessor;
++import java.security.AccessControlException;
+ import sun.awt.SunToolkit;
+ import sun.awt.PeerEvent;
+ import sun.awt.util.IdentityArrayList;
+@@ -129,6 +130,8 @@
+      */
+     boolean undecorated = false;
+ 
++    private transient boolean initialized = false;
++
+     /**
+      * Modal dialogs block all input to some top-level windows.
+      * Whether a particular window is blocked depends on dialog's type
+@@ -680,6 +683,7 @@
+         this.title = title;
+         setModalityType(modalityType);
+         SunToolkit.checkAndSetPolicy(this, false);
++        initialized = true;
+     }
+ 
+     /**
+@@ -731,6 +735,7 @@
+         this.title = title;
+         setModalityType(modalityType);
+         SunToolkit.checkAndSetPolicy(this, false);
++        initialized = true;
+     }
+ 
+     /**
+@@ -860,12 +865,9 @@
+         if (modalityType == type) {
+             return;
+         }
+-        if (type == ModalityType.TOOLKIT_MODAL) {
+-            SecurityManager sm = System.getSecurityManager();
+-            if (sm != null) {
+-                sm.checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION);
+-            }
+-        }
++
++        checkModalityPermission(type);
++
+         modalityType = type;
+         modal = (modalityType != ModalityType.MODELESS);
+     }
+@@ -1040,6 +1042,11 @@
+      */
+     @Deprecated
+     public void show() {
++        if (!initialized) {
++            throw new IllegalStateException("The dialog component " +
++                "has not been initialized properly");
++        }
++
+         beforeFirstShow = false;
+         if (!isModal()) {
+             conditionalShow(null, null);
+@@ -1615,18 +1622,50 @@
+         }
+     }
+ 
++    private void checkModalityPermission(ModalityType mt) {
++        if (mt == ModalityType.TOOLKIT_MODAL) {
++            SecurityManager sm = System.getSecurityManager();
++            if (sm != null) {
++                sm.checkPermission(
++                    SecurityConstants.TOOLKIT_MODALITY_PERMISSION
++                );
++            }
++        }
++    }
++
+     private void readObject(ObjectInputStream s)
+         throws ClassNotFoundException, IOException, HeadlessException
+     {
+         GraphicsEnvironment.checkHeadless();
+-        s.defaultReadObject();
++
++        java.io.ObjectInputStream.GetField fields =
++            s.readFields();
++
++        ModalityType localModalityType = (ModalityType)fields.get("modalityType", null);
++
++        try {
++            checkModalityPermission(localModalityType);
++        } catch (AccessControlException ace) {
++            localModalityType = DEFAULT_MODALITY_TYPE;
++        }
+ 
+         // in 1.5 or earlier modalityType was absent, so use "modal" instead
+-        if (modalityType == null) {
++        if (localModalityType == null) {
++            this.modal = fields.get("modal", false);
+             setModal(modal);
+         }
+ 
++        this.resizable = fields.get("resizable", true);
++        this.undecorated = fields.get("undecorated", false);
++        this.title = (String)fields.get("title", "");
++        this.modalityType = localModalityType;
++
+         blockedWindows = new IdentityArrayList();
++
++        SunToolkit.checkAndSetPolicy(this, false);
++
++        initialized = true;
++
+     }
+ 
+     /*
diff --git a/8005615.patch b/8005615.patch
new file mode 100644
index 0000000..a845fe8
--- /dev/null
+++ b/8005615.patch
@@ -0,0 +1,933 @@
+# HG changeset patch
+# User coffeys
+# Date 1360107230 0
+# Node ID cff0241d217f7b463d58ddcd0add8d41de9eb280
+# Parent  dabed5898de907431b524952aade46f0b6b960aa
+8005615: Java Logger fails to load tomcat logger implementation (JULI)
+Reviewed-by: mchung
+
+diff --git openjdk/jdk/src/share/classes/java/util/logging/LogManager.java openjdk/jdk/src/share/classes/java/util/logging/LogManager.java
+--- openjdk/jdk/src/share/classes/java/util/logging/LogManager.java
++++ openjdk/jdk//src/share/classes/java/util/logging/LogManager.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2013, 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
+@@ -159,7 +159,7 @@
+ 
+     // LoggerContext for system loggers and user loggers
+     private final LoggerContext systemContext = new SystemLoggerContext();
+-    private final LoggerContext userContext = new UserLoggerContext();
++    private final LoggerContext userContext = new LoggerContext();
+     private Logger rootLogger;
+ 
+     // Have we done the primordial reading of the configuration file?
+@@ -197,13 +197,13 @@
+ 
+                     // Create and retain Logger for the root of the namespace.
+                     manager.rootLogger = manager.new RootLogger();
+-                    manager.systemContext.addLogger(manager.rootLogger);
+-                    manager.userContext.addLogger(manager.rootLogger);
++                    manager.addLogger(manager.rootLogger);
++                    manager.systemContext.addLocalLogger(manager.rootLogger);
+ 
+                     // Adding the global Logger. Doing so in the Logger.<clinit>
+                     // would deadlock with the LogManager.<clinit>.
+                     Logger.global.setLogManager(manager);
+-                    manager.systemContext.addLogger(Logger.global);
++                    manager.addLogger(Logger.global);
+ 
+                     // We don't call readConfiguration() here, as we may be running
+                     // very early in the JVM startup sequence.  Instead readConfiguration
+@@ -329,7 +329,7 @@
+ 
+     // Returns the LoggerContext for the user code (i.e. application or AppContext).
+     // Loggers are isolated from each AppContext.
+-    LoggerContext getUserContext() {
++    private LoggerContext getUserContext() {
+         LoggerContext context = null;
+ 
+         SecurityManager sm = System.getSecurityManager();
+@@ -350,8 +350,8 @@
+                     if (javaAwtAccess.isMainAppContext()) {
+                         context = userContext;
+                     } else {
+-                        context = new UserLoggerContext();
+-                        context.addLogger(manager.rootLogger);
++                        context = new LoggerContext();
++                        context.addLocalLogger(manager.rootLogger);
+                     }
+                     javaAwtAccess.put(ecx, LoggerContext.class, context);
+                 }
+@@ -362,10 +362,6 @@
+         return context;
+     }
+ 
+-    LoggerContext getSystemContext() {
+-        return systemContext;
+-    }
+-
+     private List<LoggerContext> contexts() {
+         List<LoggerContext> cxs = new ArrayList<LoggerContext>();
+         cxs.add(systemContext);
+@@ -373,6 +369,58 @@
+         return cxs;
+     }
+ 
++    // 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().
++    //
++    // This method must delegate to the LogManager implementation to
++    // add a new Logger or return the one that has been added previously
++    // as a LogManager subclass may override the addLogger, getLogger,
++    // readConfiguration, and other methods.
++    Logger demandLogger(String name, String resourceBundleName) {
++        Logger result = getLogger(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 = getLogger(name);
++            } while (result == null);
++        }
++        return result;
++    }
++
++    Logger demandSystemLogger(String name, String resourceBundleName) {
++        return systemContext.demandLogger(name, resourceBundleName);
++    }
++
++    // LoggerContext maintains the logger namespace per context.
++    // The default LogManager implementation has one system context and user
++    // context.  The system context is used to maintain the namespace for
++    // all system loggers and is queried by the system code.  If a system logger
++    // doesn't exist in the user context, it'll also be added to the user context.
++    // The user context is queried by the user code and all other loggers are
++    // added in the user context.
+     static class LoggerContext {
+         // Table of named Loggers that maps names to Loggers.
+ 
+@@ -385,6 +433,12 @@
+             this.root = new LogNode(null, this);
+         }
+ 
++        Logger demandLogger(String name, String resourceBundleName) {
++            // a LogManager subclass may have its own implementation to add and
++            // get a Logger.  So delegate to the LogManager to do the work.
++            return manager.demandLogger(name, resourceBundleName);
++        }
++
+         synchronized Logger findLogger(String name) {
+             LoggerWeakRef ref = namedLoggers.get(name);
+             if (ref == null) {
+@@ -399,7 +453,9 @@
+             return logger;
+         }
+ 
+-        synchronized boolean addLogger(Logger logger) {
++        // Add a logger to this context.  This method will only set its level
++        // and process parent loggers.  It doesn't set its handlers.
++        synchronized boolean addLocalLogger(Logger logger) {
+             final String name = logger.getName();
+             if (name == null) {
+                 throw new NullPointerException();
+@@ -432,9 +488,6 @@
+                 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.
+@@ -471,49 +524,21 @@
+             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) {
++        private void processParentHandlers(final Logger logger, final String name) {
++            AccessController.doPrivileged(new PrivilegedAction<Void>() {
++                public Void run() {
++                    if (logger != manager.rootLogger) {
++                        boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true);
++                        if (!useParent) {
++                            logger.setUseParentHandlers(false);
++                        }
++                    }
++                    return null;
++                }
++            });
++
+             int ix = 1;
+             for (;;) {
+                 int ix2 = name.indexOf(".", ix);
+@@ -526,12 +551,12 @@
+                         || manager.getProperty(pname + ".handlers") != null) {
+                     // This pname has a level/handlers definition.
+                     // Make sure it exists.
+-                    demandLogger(pname);
++                    demandLogger(pname, null);
+                 }
+                 ix = ix2 + 1;
+             }
+         }
+-
++        
+         // Gets a node in our tree of logger nodes.
+         // If necessary, create it.
+         LogNode getNode(String name) {
+@@ -564,74 +589,55 @@
+     }
+ 
+     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.
+-         */
++        // Add a system logger in the system context's namespace as well as
++        // in the LogManager's namespace if not exist so that there is only
++        // one single logger of the given name.  System loggers are visible
++        // to applications unless a logger of the same name has been added.
+         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);
++                // only allocate the new system logger once
++                Logger newLogger = new Logger(name, resourceBundleName);
+                 do {
+-                    if (addLogger(newLogger)) {
++                    if (addLocalLogger(newLogger)) {
+                         // We successfully added the new Logger that we
+                         // created above so return it without refetching.
+-                        return newLogger;
++                        result = newLogger;
++                    } else {
++                        // 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);
+                     }
+-
+-                    // 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;
++            // Add the system logger to the LogManager's namespace if not exists
++            // The LogManager will set its handlers via the LogManager.addLogger method.
++            if (!manager.addLogger(result) && result.getHandlers().length == 0) {
++                // if logger already exists but handlers not set
++                final Logger l = manager.getLogger(name);
++                final Logger logger = result;
++                AccessController.doPrivileged(new PrivilegedAction<Void>() {
++                    public Void run() {
++                        for (Handler hdl : l.getHandlers()) {
++                            logger.addHandler(hdl);
++                        }
++                        return 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.
+-    // Otherwise a new logger instance is created and registered
+-    // in the LogManager global namespace.
+-    synchronized Logger demandLogger(String name) {
+-        Logger result = getLogger(name);
+-        if (result == null) {
+-            result = new Logger(name, null);
+-            addLogger(result);
+-            result = getLogger(name);
+-        }
+-        return result;
+-    }
+-
+     // Add new per logger handlers.
+     // We need to raise privilege here. All our decisions will
+     // be made based on the logging configuration, which can
+@@ -640,12 +646,6 @@
+                                     final String handlersPropertyName) {
+         AccessController.doPrivileged(new PrivilegedAction<Object>() {
+             public Object run() {
+-                if (logger != rootLogger) {
+-                    boolean useParent = getBooleanProperty(name + ".useParentHandlers", true);
+-                    if (!useParent) {
+-                        logger.setUseParentHandlers(false);
+-                    }
+-                }
+ 
+                 String names[] = parseClassNames(handlersPropertyName);
+                 for (int i = 0; i < names.length; i++) {
+@@ -674,10 +674,10 @@
+                     }
+                 }
+                 return null;
+-            }});
++            }
++        });
+     }
+ 
+-
+     // loggerRefQueue holds LoggerWeakRef objects for Logger objects
+     // that have been GC'ed.
+     private final ReferenceQueue<Logger> loggerRefQueue
+@@ -815,10 +815,15 @@
+         if (name == null) {
+             throw new NullPointerException();
+         }
+-        if (systemContext.findLogger(name) != null) {
++        LoggerContext cx = getUserContext();
++        if (cx.addLocalLogger(logger)) {
++            // Do we have a per logger handler too?
++            // Note: this will add a 200ms penalty
++            loadLoggerHandlers(logger, name, name + ".handlers");
++            return true;
++        } else {
+             return false;
+         }
+-        return getUserContext().addLogger(logger);
+     }
+ 
+     // Private method to set a level on a logger.
+@@ -839,8 +844,6 @@
+             }});
+     }
+ 
+-
+-
+     // Private method to set a parent on a logger.
+     // If necessary, we raise privilege before doing the setParent call.
+     private static void doSetParent(final Logger logger, final Logger parent) {
+@@ -875,15 +878,7 @@
+      * @return  matching logger or null if none is found
+      */
+     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);
++        return getUserContext().findLogger(name);
+     }
+ 
+     /**
+@@ -903,11 +898,7 @@
+      * @return  enumeration of logger name strings
+      */
+     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);
++        return getUserContext().getLoggerNames();
+     }
+ 
+     /**
+@@ -1229,7 +1220,6 @@
+         loadLoggerHandlers(rootLogger, null, "handlers");
+     }
+ 
+-
+     private final Permission controlPermission = new LoggingPermission("control", null);
+   
+     void checkPermission() {
+@@ -1288,7 +1278,6 @@
+     // that we only instantiate the global handlers when they
+     // are first needed.
+     private class RootLogger extends Logger {
+-
+         private RootLogger() {
+             super("", null);
+             setLevel(defaultLevel);
+diff --git openjdk/jdk/src/share/classes/java/util/logging/Logger.java openjdk/jdk/src/share/classes/java/util/logging/Logger.java
+--- openjdk/jdk/src/share/classes/java/util/logging/Logger.java
++++ openjdk/jdk/src/share/classes/java/util/logging/Logger.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2013, 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
+@@ -29,7 +29,6 @@
+ 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
+@@ -283,18 +282,32 @@
+     //
+     // 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() {
++    // These system loggers only set the resource bundle to the given
++    // resource bundle name (rather than the default system resource bundle).
++    private static class SystemLoggerHelper {
++        static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck");
++        private static boolean getBooleanProperty(final String key) {
++            String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
++                public String run() {
++                    return System.getProperty(key);
++                }
++            });
++            return Boolean.valueOf(s);
++        }
++    }
++
++    private static Logger demandLogger(String name, String resourceBundleName) {
+         LogManager manager = LogManager.getLogManager();
+         SecurityManager sm = System.getSecurityManager();
+-        if (sm != null) {
++        if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
+             // 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.demandSystemLogger(name, resourceBundleName);
+             }
+         }
+-        return manager.getUserContext();
++        return manager.demandLogger(name, resourceBundleName);
+     }
+ 
+     /**
+@@ -325,8 +338,7 @@
+      * @throws NullPointerException if the name is null.
+      */
+     public static synchronized Logger getLogger(String name) {
+-        LoggerContext context = getLoggerContext();
+-        return context.demandLogger(name);
++        return demandLogger(name, null);
+     }
+ 
+     /**
+@@ -369,8 +381,7 @@
+      * @throws NullPointerException if the name is null.
+      */
+     public static synchronized Logger getLogger(String name, String resourceBundleName) {
+-        LoggerContext context = getLoggerContext();
+-        Logger result = context.demandLogger(name, resourceBundleName);
++        Logger result = demandLogger(name, resourceBundleName);
+         if (result.resourceBundleName == null) {
+             // Note: we may get a MissingResourceException here.
+             result.setupResourceInfo(resourceBundleName);
+@@ -1300,7 +1311,8 @@
+             public ResourceBundle run() {
+                 try {
+                     return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
+-                                                    locale);
++                                                    locale,
++                                                    ClassLoader.getSystemClassLoader());
+                 } catch (MissingResourceException e) {
+                     throw new InternalError(e.toString());
+                 }
+diff --git openjdk/jdk/test/java/util/logging/CustomLogManager.java openjdk/jdk/test/java/util/logging/CustomLogManager.java
+new file mode 100644
+--- /dev/null
++++ openjdk/jdk/test/java/util/logging/CustomLogManager.java
+@@ -0,0 +1,209 @@
++/*
++ * Copyright (c) 2013, 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
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.io.*;
++import java.util.*;
++import java.util.logging.*;
++
++/*
++ * Custom LogManager implementation to verify that the implementation delegates
++ * to the LogManager subclass to register both system logger and user logger.
++ *
++ * The LogManager implementation is the one configuring the logger's property
++ * such as level, handler, etc.
++ */
++public class CustomLogManager extends LogManager {
++    static LogManager INSTANCE;
++    Map<String, Logger> namedLoggers = new HashMap<String, Logger>();
++    Properties props = initConfig();
++    public CustomLogManager() {
++        if (INSTANCE != null) {
++            throw new RuntimeException("CustomLogManager already created");
++        }
++        INSTANCE = this;
++    }
++
++    private boolean getBooleanProperty(String key, boolean value) {
++        String s = props.getProperty(key);
++        if (s == null)
++            return value;
++
++        s = s.toLowerCase();
++        if (s.equals("true") || s.equals("1")) {
++           return true;
++        } else if (s.equals("false") || s.equals("0")) {
++           return false;
++        }
++        return value;
++    }
++
++    public synchronized boolean addLogger(Logger logger) {
++        String name = logger.getName();
++        if (namedLoggers.containsKey(name)) {
++            return false;
++        }
++        namedLoggers.put(name, logger);
++        // set level
++        if (props.get(name + ".level") != null) {
++            logger.setLevel(Level.parse(props.getProperty(name + ".level")));
++        }
++        // add handlers
++        if (props.get(name + ".handlers") != null && logger.getHandlers().length == 0) {
++            logger.addHandler(new CustomHandler());
++        }
++        if (getBooleanProperty(name + ".useParentHandlers", true) == false) {
++            logger.setUseParentHandlers(false);
++        }
++        // add parent loggers
++        int ix = 1;
++        for (;;) {
++            int ix2 = name.indexOf(".", ix);
++            if (ix2 < 0) {
++                break;
++            }
++            String pname = name.substring(0, ix2);
++            if (props.get(pname + ".level") != null ||
++                props.get(pname + ".handlers") != null) {
++                // This pname has a level/handlers definition.
++                // Make sure it exists.
++                //
++                // The test doesn't set the parent for simplicity.
++                if (!namedLoggers.containsKey(pname)) {
++                    Logger parent = Logger.getLogger(pname);
++                    if (getBooleanProperty(pname + ".useParentHandlers", true) == false) {
++                        parent.setUseParentHandlers(false);
++                    }
++                }
++            }
++            ix = ix2 + 1;
++        }
++        return true;
++    }
++
++    public synchronized Logger getLogger(String name) {
++        return namedLoggers.get(name);
++    }
++
++    public synchronized Enumeration<String> getLoggerNames() {
++        return Collections.enumeration(namedLoggers.keySet());
++    }
++
++    public String getProperty(String name) {
++        return props.getProperty(name);
++    }
++
++    public void readConfiguration() {
++        // do nothing
++    }
++
++    public void readConfiguration(InputStream ins) {
++        // do nothing
++    }
++
++    private Properties initConfig() {
++        Properties props = new Properties();
++        props.put(".level", "CONFIG");
++        props.put("CustomLogManagerTest.level", "WARNING");
++        props.put("CustomLogManagerTest.handlers", "CustomLogManager$CustomHandler");
++        props.put("SimpleLogManager.level", "INFO");
++        props.put("SimpleLogManager.handlers", "CustomLogManager$CustomHandler");
++        props.put("CustomLogManager$CustomHandler.level", "WARNING");
++        props.put(".handlers", "CustomLogManager$CustomHandler");
++        props.put("org.foo.bar.level", "SEVERE");
++        props.put("org.foo.bar.useParentHandlers", "true");
++        props.put("org.foo.handlers", "CustomLogManager$CustomHandler");
++        props.put("org.foo.useParentHandlers", "false");
++        props.put("org.openjdk.level", "SEVERE");
++        props.put("org.openjdk.handlers", "CustomLogManager$CustomHandler");
++        props.put("org.openjdk.core.level", "INFO");
++        props.put("org.openjdk.core.useParentHandlers", "false");
++
++        return props;
++    }
++
++    public static void checkLogger(String name) {
++        checkLogger(name, null);
++    }
++
++    public static void checkLogger(String name, String resourceBundleName) {
++        Logger logger = INSTANCE.getLogger(name);
++        if (logger == null) {
++            throw new RuntimeException("Logger \"" + name + "\" not exist");
++        }
++        System.out.format("Logger \"%s\" level=%s handlers=%s resourcebundle=%s useParentHandlers=%s%n",
++            name, logger.getLevel(),
++            Arrays.toString(logger.getHandlers()),
++            logger.getResourceBundleName(),
++            logger.getUseParentHandlers());
++
++        String rb = logger.getResourceBundleName();
++        if (rb != resourceBundleName && (rb == null || rb.equals(resourceBundleName))) {
++            throw new RuntimeException("Logger \"" + name +
++                "\" unexpected resource bundle: " + rb);
++        }
++
++        String value = INSTANCE.getProperty(name + ".level");
++        String level = logger.getLevel() != null ? logger.getLevel().getName() : null;
++        if (level != value && (level == null || level.equals(value))) {
++            throw new RuntimeException("Logger \"" + name + "\" unexpected level: " + level);
++        }
++
++        Handler[] handlers = logger.getHandlers();
++        String hdl = INSTANCE.getProperty(name + ".handlers");
++        if ((hdl == null && handlers.length != 0) ||
++            (hdl != null && handlers.length != 1)) {
++            throw new RuntimeException("Logger \"" + name + "\" unexpected handler: " +
++                Arrays.toString(handlers));
++        }
++
++        String s = INSTANCE.getProperty(name + ".useParentHandlers");
++        boolean uph = (s != null && s.equals("false")) ? false : true;
++        if (logger.getUseParentHandlers() != uph) {
++            throw new RuntimeException("Logger \"" + name + "\" unexpected useParentHandlers: " +
++                logger.getUseParentHandlers());
++        }
++        checkParents(name);
++    }
++
++    private static void checkParents(String name) {
++        int ix = 1;
++        for (;;) {
++            int ix2 = name.indexOf(".", ix);
++            if (ix2 < 0) {
++                break;
++            }
++            String pname = name.substring(0, ix2);
++            if (INSTANCE.getProperty(pname + ".level") != null ||
++                INSTANCE.getProperty(pname + ".handlers") != null) {
++                // This pname has a level/handlers definition.
++                // Make sure it exists.
++                checkLogger(pname);
++            }
++            ix = ix2 + 1;
++        }
++    }
++
++    // only CustomLogManager can create an instance of CustomHandler
++    private class CustomHandler extends StreamHandler {
++    }
++}
+diff --git openjdk/jdk/test/java/util/logging/CustomLogManagerTest.java openjdk/jdk/test/java/util/logging/CustomLogManagerTest.java
+new file mode 100644
+--- /dev/null
++++ openjdk/jdk/test/java/util/logging/CustomLogManagerTest.java
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2013, 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
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.io.*;
++import java.util.*;
++
++import java.util.logging.*;
++
++/*
++ * @test
++ * @bug 8005615
++ * @summary Add loggers to custom log manager
++ *
++ * @compile -XDignore.symbol.file CustomLogManagerTest.java CustomLogManager.java
++ * @run main/othervm -Djava.util.logging.manager=CustomLogManager CustomLogManagerTest
++ */
++public class CustomLogManagerTest {
++    private static final String RESOURCE_BUNDLE = "sun.util.logging.resources.logging";
++    public static void main(String[] args) {
++        String mgr = System.getProperty("java.util.logging.manager");
++        if (!mgr.equals("CustomLogManager")) {
++            throw new RuntimeException("java.util.logging.manager not set");
++        }
++
++        Logger.getLogger(CustomLogManagerTest.class.getName());
++        Logger.getLogger("org.foo.Foo");
++        Logger.getLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
++
++        if (LogManager.getLogManager() != CustomLogManager.INSTANCE) {
++             throw new RuntimeException(LogManager.getLogManager() + " not CustomLogManager");
++        }
++
++        CustomLogManager.checkLogger(CustomLogManagerTest.class.getName());
++        CustomLogManager.checkLogger("org.foo.Foo");
++        CustomLogManager.checkLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
++        CustomLogManager.checkLogger("global");
++        CustomLogManager.checkLogger("");
++    }
++}
+diff --git openjdk/jdk/test/java/util/logging/SimpleLogManager.java openjdk/jdk/test/java/util/logging/SimpleLogManager.java
+new file mode 100644
+--- /dev/null
++++ openjdk/jdk/test/java/util/logging/SimpleLogManager.java
+@@ -0,0 +1,108 @@
++/*
++ * Copyright (c) 2013, 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
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.util.*;
++import java.util.logging.*;
++
++/*
++ * @test
++ * @bug 8005615
++ * @summary A LogManager subclass overrides its own implementation of named
++ *          logger (see the subclassing information in the Logger class specification)
++ *
++ * @compile -XDignore.symbol.file CustomLogManager.java SimpleLogManager.java
++ * @run main/othervm -Djava.util.logging.manager=SimpleLogManager SimpleLogManager
++ */
++public class SimpleLogManager extends CustomLogManager {
++    public static void main(String[] args) {
++        String classname = System.getProperty("java.util.logging.manager");
++        if (!classname.equals("SimpleLogManager")) {
++            throw new RuntimeException("java.util.logging.manager not set");
++        }
++
++        Logger logger = Logger.getLogger(SimpleLogManager.class.getName());
++        Logger.getLogger("org.foo.bar.Foo");
++
++        LogManager mgr = LogManager.getLogManager();
++        if (mgr != CustomLogManager.INSTANCE || !(mgr instanceof SimpleLogManager)) {
++             throw new RuntimeException(LogManager.getLogManager() + " not SimpleLogManager");
++        }
++
++        checkCustomLogger(SimpleLogManager.class.getName(), null);
++        checkCustomLogger("org.foo.bar.Foo", null);
++
++        // ## The LogManager.demandLogger method does not handle custom log manager
++        // ## that overrides the getLogger method to return a custom logger
++        // ## (see the test case in 8005640).  Logger.getLogger may return
++        // ## a Logger instance but LogManager overrides it with a custom Logger
++        // ## instance like this case.
++        //
++        // However, the specification of LogManager and Logger subclassing is
++        // not clear whether this is supported or not.  The following check
++        // just captures the current behavior.
++        if (logger instanceof CustomLogger) {
++            throw new RuntimeException(logger + " not CustomLogger");
++        }
++    }
++
++    private static void checkCustomLogger(String name, String resourceBundleName) {
++        CustomLogManager.checkLogger(name, resourceBundleName);
++        Logger logger1 = Logger.getLogger(name);
++        Logger logger2 = LogManager.getLogManager().getLogger(name);
++        if (logger1 != logger2) {
++            throw new RuntimeException(logger1 + " != " + logger2);
++        }
++        if (!(logger1 instanceof CustomLogger)) {
++            throw new RuntimeException(logger1 + " not CustomLogger");
++        }
++    }
++
++    /*
++     * This SimpleLogManager overrides the addLogger method to replace
++     * the given logger with a custom logger.
++     *
++     * It's unclear what the recommended way to use custom logger is.
++     * A LogManager subclass might override the getLogger method to return
++     * a custom Logger and create a new custom logger if not exist so that
++     * Logger.getLogger() can return a custom Logger instance but that violates
++     * the LogManager.getLogger() spec which should return null if not found.
++     */
++    public synchronized boolean addLogger(Logger logger) {
++        String name = logger.getName();
++        if (namedLoggers.containsKey(name)) {
++            return false;
++        }
++        CustomLogger newLogger = new CustomLogger(logger);
++        super.addLogger(newLogger);
++        return true;
++    }
++
++    public class CustomLogger extends Logger {
++        CustomLogger(Logger logger) {
++            super(logger.getName(), logger.getResourceBundleName());
++        }
++        CustomLogger(String name) {
++            super(name, null);
++        }
++    }
++}
diff --git a/java-1.6.0-openjdk.spec b/java-1.6.0-openjdk.spec
index fff1337..75e3b16 100644
--- a/java-1.6.0-openjdk.spec
+++ b/java-1.6.0-openjdk.spec
@@ -173,7 +173,9 @@ Patch2:   java-1.6.0-openjdk-java-access-bridge-idlj.patch
 Patch3:	  java-1.6.0-openjdk-java-access-bridge-security.patch
 Patch4:   java-1.6.0-openjdk-accessible-toolkit.patch
 
-Patch8:   revertTwoWrongSecurityPatches2013-02-06.patch
+Patch8:   7201064.patch
+Patch9:   8005615.patch
+
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
@@ -389,11 +391,14 @@ export CFLAGS="$CFLAGS -mieee"
 make stamps/patch-ecj.stamp
 %endif
 
-#reverting 6664509 and 7201064 from 1.11.6
-patch -p0 < %{PATCH8}
 
 make patch
 
+#reverting 7201064 from 1.11.6
+patch -l -R -p0 < %{PATCH8}
+#fixing 6664509 from 1.11.6
+patch -l -p0 < %{PATCH9}
+
 patch -l -p0 < %{PATCH3}
 patch -l -p0 < %{PATCH4}
 patch -f -l -p0 < %{PATCH5} || true
@@ -790,9 +795,6 @@ fi
 exit 0
 
 
-
-
-
 %files -f %{name}.files
 %defattr(-,root,root,-)
 %doc %{buildoutputdir}/j2sdk-image/jre/ASSEMBLY_EXCEPTION
@@ -905,6 +907,11 @@ exit 0
 %doc %{_javadocdir}/%{name}
 
 %changelog
+* Wed Feb 06 2013 Jiri Vanek <jvanek at redhat.com> - 1:1.6.0.0-1.71.1.11.6
+- removed patch8 revertTwoWrongSecurityPatches2013-02-06.patch
+- added patch8:   7201064.patch to be reverted
+- added patch9:   8005615.patch to fix the 6664509.patch
+
 * Wed Feb 06 2013 Jiri Vanek <jvanek at redhat.com> - 1:1.6.0.0-1.70.1.11.6
 - added patch8 revertTwoWrongSecurityPatches2013-02-06.patch
   to remove   6664509 and 7201064 from 1.11.6 tarball


More information about the scm-commits mailing list