diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java index 32b2a57f025a3261a6b6315f647a233960d84dea..efc18c520c0100f998d273fac28d6c3bff1ae9a5 100644 --- a/src/share/classes/java/util/logging/Logger.java +++ b/src/share/classes/java/util/logging/Logger.java @@ -555,7 +555,9 @@ public class Logger { * Even although the new logger is anonymous, it is configured * to have the root logger ("") as its parent. This means that * by default it inherits its effective level and handlers - * from the root logger. + * from the root logger. Changing its parent via the + * {@link #setParent(java.util.logging.Logger) setParent} method + * will still require the security permission specified by that method. *

* * @return a newly created private Logger @@ -579,7 +581,9 @@ public class Logger { * Even although the new logger is anonymous, it is configured * to have the root logger ("") as its parent. This means that * by default it inherits its effective level and handlers - * from the root logger. + * from the root logger. Changing its parent via the + * {@link #setParent(java.util.logging.Logger) setParent} method + * will still require the security permission specified by that method. *

* @param resourceBundleName name of ResourceBundle to be used for localizing * messages for this logger. @@ -648,8 +652,9 @@ public class Logger { * be published. * * @param newFilter a filter object (may be null) - * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * @throws SecurityException if a security manager exists, + * this logger is not anonymous, and the caller + * does not have LoggingPermission("control"). */ public void setFilter(Filter newFilter) throws SecurityException { checkPermission(); @@ -1629,8 +1634,9 @@ public class Logger { * (non-null) level value. * * @param newLevel the new value for the log level (may be null) - * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * @throws SecurityException if a security manager exists, + * this logger is not anonymous, and the caller + * does not have LoggingPermission("control"). */ public void setLevel(Level newLevel) throws SecurityException { checkPermission(); @@ -1686,8 +1692,9 @@ public class Logger { * that essentially act as default handlers for all loggers. * * @param handler a logging Handler - * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * @throws SecurityException if a security manager exists, + * this logger is not anonymous, and the caller + * does not have LoggingPermission("control"). */ public void addHandler(Handler handler) throws SecurityException { // Check for null handler @@ -1702,8 +1709,9 @@ public class Logger { * Returns silently if the given Handler is not found or is null * * @param handler a logging Handler - * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * @throws SecurityException if a security manager exists, + * this logger is not anonymous, and the caller + * does not have LoggingPermission("control"). */ public void removeHandler(Handler handler) throws SecurityException { checkPermission(); @@ -1730,8 +1738,9 @@ public class Logger { * * @param useParentHandlers true if output is to be sent to the * logger's parent. - * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * @throws SecurityException if a security manager exists, + * this logger is not anonymous, and the caller + * does not have LoggingPermission("control"). */ public void setUseParentHandlers(boolean useParentHandlers) { checkPermission(); @@ -1894,8 +1903,9 @@ public class Logger { * {@linkplain ResourceBundle#getBaseBundleName base name}, * or if this logger already has a resource bundle set but * the given bundle has a different base name. - * @throws SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * @throws SecurityException if a security manager exists, + * this logger is not anonymous, and the caller + * does not have LoggingPermission("control"). * @since 1.8 */ public void setResourceBundle(ResourceBundle bundle) { @@ -1952,14 +1962,20 @@ public class Logger { * It should not be called from application code. *

* @param parent the new parent logger - * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * @throws SecurityException if a security manager exists and if + * the caller does not have LoggingPermission("control"). */ public void setParent(Logger parent) { if (parent == null) { throw new NullPointerException(); } - checkPermission(); + + // check permission for all loggers, including anonymous loggers + if (manager == null) { + manager = LogManager.getLogManager(); + } + manager.checkPermission(); + doSetParent(parent); } diff --git a/test/java/util/logging/AnonymousLogger/TestAnonymousLogger.java b/test/java/util/logging/AnonymousLogger/TestAnonymousLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..accb2b30bc7c412344b1f7facd724d7835f291a1 --- /dev/null +++ b/test/java/util/logging/AnonymousLogger/TestAnonymousLogger.java @@ -0,0 +1,133 @@ +/* + * 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.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.LinkedHashSet; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.logging.Filter; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +/** + * @test + * @bug 8026863 + * @summary checks that anonymous logger setters work as expected when a + * security manager is set, and checks that getters return expected + * values. + * @run main/othervm TestAnonymousLogger + */ +public class TestAnonymousLogger { + + final public static class TestHandler extends Handler { + @Override + public void publish(LogRecord record) { + System.out.println(new SimpleFormatter().format(record)); + } + @Override + public void flush() { + System.out.flush(); + } + @Override + public void close() { + flush(); + } + } + + final public static class TestFilter implements Filter { + @Override + public boolean isLoggable(LogRecord record) { + return true; + } + } + + final public static class TestBundle extends ResourceBundle { + Set keys = Collections.synchronizedSet(new LinkedHashSet<>()); + @Override + protected Object handleGetObject(String key) { + keys.add(key); + return "[LOCALIZED] "+key; + } + @Override + public Enumeration getKeys() { + return Collections.enumeration(keys); + } + } + + public static void main(String[] args) { + System.setSecurityManager(new SecurityManager()); + Logger anonymous = Logger.getAnonymousLogger(); + + final TestHandler handler = new TestHandler(); + final TestFilter filter = new TestFilter(); + final ResourceBundle bundle = ResourceBundle.getBundle(TestBundle.class.getName()); + anonymous.setLevel(Level.FINEST); + anonymous.addHandler(handler); + anonymous.setFilter(filter); + anonymous.setUseParentHandlers(true); + anonymous.setResourceBundle(bundle); + + if (anonymous.getLevel() != Level.FINEST) { + throw new RuntimeException("Unexpected level: " + anonymous.getLevel()); + } else { + System.out.println("Got expected level: " + anonymous.getLevel()); + } + if (!Arrays.asList(anonymous.getHandlers()).contains(handler)) { + throw new RuntimeException("Expected handler not found in: " + + Arrays.asList(anonymous.getHandlers())); + } else { + System.out.println("Got expected handler in: " + Arrays.asList(anonymous.getHandlers())); + } + if (anonymous.getFilter() != filter) { + throw new RuntimeException("Unexpected filter: " + anonymous.getFilter()); + } else { + System.out.println("Got expected filter: " + anonymous.getFilter()); + } + if (!anonymous.getUseParentHandlers()) { + throw new RuntimeException("Unexpected flag: " + anonymous.getUseParentHandlers()); + } else { + System.out.println("Got expected flag: " + anonymous.getUseParentHandlers()); + } + if (anonymous.getResourceBundle() != bundle) { + throw new RuntimeException("Unexpected bundle: " + anonymous.getResourceBundle()); + } else { + System.out.println("Got expected bundle: " + anonymous.getResourceBundle()); + } + try { + anonymous.setParent(Logger.getLogger("foo.bar")); + throw new RuntimeException("Expected SecurityException not raised!"); + } catch (SecurityException x) { + System.out.println("Got expected exception: " + x); + } + if (anonymous.getParent() != Logger.getLogger("")) { + throw new RuntimeException("Unexpected parent: " + anonymous.getParent()); + } else { + System.out.println("Got expected parent: " + anonymous.getParent()); + } + } + +}