[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