From eb8ee8bdc7c170910abc9aa18de1e22677160358 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 9 Jun 2025 16:01:18 +0000 Subject: [PATCH] 8358731: Remove jdk.internal.access.JavaAWTAccess.java Reviewed-by: dfuchs, serb --- .../jdk/internal/access/JavaAWTAccess.java | 36 -- .../jdk/internal/access/SharedSecrets.java | 11 - .../share/classes/sun/awt/AppContext.java | 63 --- .../logging/LogManagerAppContextDeadlock.java | 381 ------------- .../java/util/logging/TestGetLoggerNPE.java | 99 ---- .../util/logging/TestUILoggerContext.java | 520 ------------------ 6 files changed, 1110 deletions(-) delete mode 100644 src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java delete mode 100644 test/jdk/java/util/logging/LogManagerAppContextDeadlock.java delete mode 100644 test/jdk/java/util/logging/TestGetLoggerNPE.java delete mode 100644 test/jdk/java/util/logging/TestUILoggerContext.java diff --git a/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java deleted file mode 100644 index a4c170ca918..00000000000 --- a/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package jdk.internal.access; - -public interface JavaAWTAccess { - - // Returns the AppContext used for applet logging isolation, or null if - // no isolation is required. - // If there's no applet, or if the caller is a stand alone application, - // or running in the main app context, returns null. - // Otherwise, returns the AppContext of the calling applet. - public Object getAppletContext(); -} diff --git a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java index bc955a76abb..5c6212d0bf6 100644 --- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java +++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java @@ -59,7 +59,6 @@ import javax.security.auth.x500.X500Principal; */ public class SharedSecrets { - private static JavaAWTAccess javaAWTAccess; private static JavaAWTFontAccess javaAWTFontAccess; private static JavaBeansAccess javaBeansAccess; private static JavaLangAccess javaLangAccess; @@ -321,16 +320,6 @@ public class SharedSecrets { javaUtilZipFileAccess = access; } - public static void setJavaAWTAccess(JavaAWTAccess jaa) { - javaAWTAccess = jaa; - } - - public static JavaAWTAccess getJavaAWTAccess() { - // this may return null in which case calling code needs to - // provision for. - return javaAWTAccess; - } - public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) { javaAWTFontAccess = jafa; } diff --git a/src/java.desktop/share/classes/sun/awt/AppContext.java b/src/java.desktop/share/classes/sun/awt/AppContext.java index a35d89f6a0c..3b93f1d2755 100644 --- a/src/java.desktop/share/classes/sun/awt/AppContext.java +++ b/src/java.desktop/share/classes/sun/awt/AppContext.java @@ -42,8 +42,6 @@ import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; import java.lang.ref.SoftReference; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; import sun.util.logging.PlatformLogger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; @@ -746,67 +744,6 @@ public final class AppContext { return changeSupport.getPropertyChangeListeners(propertyName); } - // Set up JavaAWTAccess in SharedSecrets - static { - SharedSecrets.setJavaAWTAccess(new JavaAWTAccess() { - private boolean hasRootThreadGroup(final AppContext ecx) { - return ecx.threadGroup.getParent() == null; - } - - /** - * Returns the AppContext used for applet logging isolation, or null if - * the default global context can be used. - * If there's no applet, or if the caller is a stand alone application, - * or running in the main app context, returns null. - * Otherwise, returns the AppContext of the calling applet. - * @return null if the global default context can be used, - * an AppContext otherwise. - **/ - public Object getAppletContext() { - // There's no AppContext: return null. - // No need to call getAppContext() if numAppContext == 0: - // it means that no AppContext has been created yet, and - // we don't want to trigger the creation of a main app - // context since we don't need it. - if (numAppContexts.get() == 0) return null; - - AppContext ecx = null; - - // Not sure we really need to re-check numAppContexts here. - // If all applets have gone away then we could have a - // numAppContexts coming back to 0. So we recheck - // it here because we don't want to trigger the - // creation of a main AppContext in that case. - // This is probably not 100% MT-safe but should reduce - // the window of opportunity in which that issue could - // happen. - if (numAppContexts.get() > 0) { - // Defaults to thread group caching. - // This is probably not required as we only really need - // isolation in a deployed applet environment, in which - // case ecx will not be null when we reach here - // However it helps emulate the deployed environment, - // in tests for instance. - ecx = ecx != null ? ecx : getAppContext(); - } - - // getAppletContext() may be called when initializing the main - // app context - in which case mainAppContext will still be - // null. To work around this issue we simply use - // AppContext.threadGroup.getParent() == null instead, since - // mainAppContext is the only AppContext which should have - // the root TG as its thread group. - // See: JDK-8023258 - final boolean isMainAppContext = ecx == null - || mainAppContext == ecx - || mainAppContext == null && hasRootThreadGroup(ecx); - - return isMainAppContext ? null : ecx; - } - - }); - } - public static T getSoftReferenceValue(Object key, Supplier supplier) { diff --git a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java b/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java deleted file mode 100644 index f39b46b43d1..00000000000 --- a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2013, 2022, 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.lang.management.ManagementFactory; -import java.lang.management.ThreadInfo; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.util.Enumeration; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/** - * @test - * @bug 8065991 - * @summary check that when LogManager is initialized, a deadlock similar - * to that described in 8065709 will not occur. - * @modules java.base/jdk.internal.access - * java.logging - * java.management - * @run main/othervm LogManagerAppContextDeadlock UNSECURE - * @run main/othervm LogManagerAppContextDeadlock SECURE - * - * @author danielfuchs - */ -public class LogManagerAppContextDeadlock { - - public static final Semaphore sem = new Semaphore(0); - public static final Semaphore sem2 = new Semaphore(0); - public static final Semaphore sem3 = new Semaphore(-2); - public static volatile boolean goOn = true; - public static volatile Exception thrown; - - // Emulate EventQueue - static class FakeEventQueue { - static final Logger logger = Logger.getLogger("foo"); - } - - // Emulate AppContext - static class FakeAppContext { - - static final AtomicInteger numAppContexts = new AtomicInteger(0); - static final class FakeAppContextLock {} - static final FakeAppContextLock lock = new FakeAppContextLock(); - static volatile FakeAppContext appContext; - - final FakeEventQueue queue; - FakeAppContext() { - appContext = this; - numAppContexts.incrementAndGet(); - // release sem2 to let Thread t2 call Logger.getLogger(). - sem2.release(); - try { - // Wait until we JavaAWTAccess is called by LogManager. - // Thread 2 will call Logger.getLogger() which will - // trigger a call to JavaAWTAccess - which will release - // sem, thus ensuring that Thread #2 is where we want it. - sem.acquire(); - System.out.println("Sem acquired: Thread #2 has called JavaAWTAccess"); - } catch(InterruptedException x) { - Thread.interrupted(); - } - queue = new FakeEventQueue(); - } - - static FakeAppContext getAppContext() { - synchronized (lock) { - if (numAppContexts.get() == 0) { - return new FakeAppContext(); - } - return appContext; - } - } - - static { - SharedSecrets.setJavaAWTAccess(new JavaAWTAccess() { - @Override - public Object getAppletContext() { - if (numAppContexts.get() == 0) return null; - // We are in JavaAWTAccess, we can release sem and let - // FakeAppContext constructor proceeed. - System.out.println("Releasing Sem"); - sem.release(); - return getAppContext(); - } - - }); - } - - } - - - // Test with or without a security manager - public static enum TestCase { - UNSECURE, SECURE; - public void run() throws Exception { - System.out.println("Running test case: " + name()); - Configure.setUp(this); - test(this); - } - } - - public static void test(TestCase test) throws Exception { - Thread t1 = new Thread() { - @Override - public void run() { - sem3.release(); - System.out.println("FakeAppContext.getAppContext()"); - FakeAppContext.getAppContext(); - System.out.println("Done: FakeAppContext.getAppContext()"); - } - }; - t1.setDaemon(true); - t1.start(); - Thread t2 = new Thread() { - public Object logger; - public void run() { - sem3.release(); - try { - // Wait until Thread1 is in FakeAppContext constructor - sem2.acquire(); - System.out.println("Sem2 acquired: Thread #1 will be waiting to acquire Sem"); - } catch (InterruptedException ie) { - Thread.interrupted(); - } - System.out.println("Logger.getLogger(name).info(name)"); - // stick the logger in an instance variable to prevent it - // from being garbage collected before the main thread - // calls LogManager.getLogger() below. - logger = Logger.getLogger(test.name());//.info(name); - System.out.println("Done: Logger.getLogger(name).info(name)"); - } - }; - t2.setDaemon(true); - t2.start(); - System.out.println("Should exit now..."); - Thread detector = new DeadlockDetector(); - detector.start(); - - // Wait for the 3 threads to start - sem3.acquire(); - - // Now wait for t1 & t2 to finish, or for a deadlock to be detected. - while (goOn && (t1.isAlive() || t2.isAlive())) { - if (t2.isAlive()) t2.join(1000); - if (test == TestCase.UNSECURE && System.getSecurityManager() == null) { - // if there's no security manager, AppContext.getAppContext() is - // not called - so Thread t2 will not end up calling - // sem.release(). In that case we must release the semaphore here - // so that t1 can proceed. - if (LogManager.getLogManager().getLogger(TestCase.UNSECURE.name()) != null) { - // means Thread t2 has created the logger - sem.release(); - } - } - if (t1.isAlive()) t1.join(1000); - } - if (thrown != null) { - throw thrown; - } - } - - // Thrown by the deadlock detector - static final class DeadlockException extends RuntimeException { - public DeadlockException(String message) { - super(message); - } - @Override - public void printStackTrace() { - } - } - - public static void main(String[] args) throws Exception { - - if (args.length == 0) { - args = new String[] { "SECURE" }; - } - - // If we don't initialize LogManager here, there will be - // a deadlock. - // See - // for more details. - Logger.getLogger("main").info("starting..."); - try { - TestCase.valueOf(args[0]).run(); - System.out.println("Test "+args[0]+" Passed"); - } catch(Throwable t) { - System.err.println("Test " + args[0] +" failed: " + t); - t.printStackTrace(); - } - } - - // Called by the deadlock detector when a deadlock is found. - static void fail(Exception x) { - x.printStackTrace(); - if (thrown == null) { - thrown = x; - } - goOn = false; - } - - // A thread that detect deadlocks. - static final class DeadlockDetector extends Thread { - - public DeadlockDetector() { - this.setDaemon(true); - } - - @Override - public void run() { - sem3.release(); - Configure.doPrivileged(this::loop); - } - public void loop() { - while(goOn) { - try { - long[] ids = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); - ids = ids == null ? new long[0] : ids; - if (ids.length == 1) { - throw new RuntimeException("Found 1 deadlocked thread: "+ids[0]); - } else if (ids.length > 0) { - ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(ids, Integer.MAX_VALUE); - System.err.println("Found "+ids.length+" deadlocked threads: "); - for (ThreadInfo inf : infos) { - System.err.println(inf); - } - throw new DeadlockException("Found "+ids.length+" deadlocked threads"); - } - Thread.sleep(100); - } catch(InterruptedException | RuntimeException x) { - fail(x); - } - } - } - - } - - // A helper class to configure the security manager for the test, - // and bypass it when needed. - static class Configure { - static Policy policy = null; - static final ThreadLocal allowAll = new ThreadLocal() { - @Override - protected AtomicBoolean initialValue() { - return new AtomicBoolean(false); - } - }; - static void setUp(TestCase test) { - switch (test) { - case SECURE: - if (policy == null && System.getSecurityManager() != null) { - throw new IllegalStateException("SecurityManager already set"); - } else if (policy == null) { - policy = new SimplePolicy(TestCase.SECURE, allowAll); - Policy.setPolicy(policy); - System.setSecurityManager(new SecurityManager()); - } - if (System.getSecurityManager() == null) { - throw new IllegalStateException("No SecurityManager."); - } - if (policy == null) { - throw new IllegalStateException("policy not configured"); - } - break; - case UNSECURE: - if (System.getSecurityManager() != null) { - throw new IllegalStateException("SecurityManager already set"); - } - break; - default: - new InternalError("No such testcase: " + test); - } - } - static void doPrivileged(Runnable run) { - allowAll.get().set(true); - try { - run.run(); - } finally { - allowAll.get().set(false); - } - } - } - - // A Helper class to build a set of permissions. - static final class PermissionsBuilder { - final Permissions perms; - public PermissionsBuilder() { - this(new Permissions()); - } - public PermissionsBuilder(Permissions perms) { - this.perms = perms; - } - public PermissionsBuilder add(Permission p) { - perms.add(p); - return this; - } - public PermissionsBuilder addAll(PermissionCollection col) { - if (col != null) { - for (Enumeration e = col.elements(); e.hasMoreElements(); ) { - perms.add(e.nextElement()); - } - } - return this; - } - public Permissions toPermissions() { - final PermissionsBuilder builder = new PermissionsBuilder(); - builder.addAll(perms); - return builder.perms; - } - } - - // Policy for the test... - public static class SimplePolicy extends Policy { - - static final Policy DEFAULT_POLICY = Policy.getPolicy(); - - final Permissions permissions; - final Permissions allPermissions; - final ThreadLocal allowAll; // actually: this should be in a thread locale - public SimplePolicy(TestCase test, ThreadLocal allowAll) { - this.allowAll = allowAll; - // we don't actually need any permission to create our - // FileHandlers because we're passing invalid parameters - // which will make the creation fail... - permissions = new Permissions(); - permissions.add(new RuntimePermission("accessClassInPackage.jdk.internal.access")); - - // these are used for configuring the test itself... - allPermissions = new Permissions(); - allPermissions.add(new java.security.AllPermission()); - - } - - @Override - public boolean implies(ProtectionDomain domain, Permission permission) { - if (allowAll.get().get()) return allPermissions.implies(permission); - return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission); - } - - @Override - public PermissionCollection getPermissions(CodeSource codesource) { - return new PermissionsBuilder().addAll(allowAll.get().get() - ? allPermissions : permissions).toPermissions(); - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain domain) { - return new PermissionsBuilder().addAll(allowAll.get().get() - ? allPermissions : permissions).toPermissions(); - } - } - -} diff --git a/test/jdk/java/util/logging/TestGetLoggerNPE.java b/test/jdk/java/util/logging/TestGetLoggerNPE.java deleted file mode 100644 index 02c57b75067..00000000000 --- a/test/jdk/java/util/logging/TestGetLoggerNPE.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013, 2024, 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.PrintStream; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/* - * @test - * @bug 8025512 - * - * @summary NPE with logging while launching webstart - * - * @modules java.base/jdk.internal.access - * java.logging - * @build TestGetLoggerNPE - * @run main/othervm TestGetLoggerNPE getLogger - * @run main/othervm TestGetLoggerNPE getLogManager - */ -public class TestGetLoggerNPE { - static volatile Throwable thrown = null; - public static void main(String[] args) throws Exception { - final String testCase = args.length == 0 ? "getLogger" : args[0]; - final JavaAWTAccessStub access = new JavaAWTAccessStub(); - SharedSecrets.setJavaAWTAccess(access); - final ThreadGroup tg = new ThreadGroup("TestGroup"); - Thread t = new Thread(tg, "test") { - public void run() { - try { - access.setContext(Context.ONE); - final PrintStream out = System.out; - System.setOut(null); - try { - if ("getLogger".equals(testCase)) { - Logger.getLogger("sun.plugin"); - } else { - LogManager.getLogManager(); - } - } finally { - System.setOut(out); - } - - System.out.println(Logger.global); - } catch (Throwable x) { - x.printStackTrace(); - thrown = x; - } - } - }; - t.start(); - t.join(); - if (thrown == null) { - System.out.println("PASSED: " + testCase); - } else { - System.err.println("FAILED: " + testCase); - throw new Error("Test failed: " + testCase + " - " + thrown, thrown); - } - - } - - static enum Context { ONE, TWO }; - - static final class JavaAWTAccessStub implements JavaAWTAccess { - private static final InheritableThreadLocal context = new InheritableThreadLocal<>(); - - - public void setContext(Context context) { - JavaAWTAccessStub.context.set(context); - } - - @Override - public Object getAppletContext() { - return context.get(); - } - - } - -} diff --git a/test/jdk/java/util/logging/TestUILoggerContext.java b/test/jdk/java/util/logging/TestUILoggerContext.java deleted file mode 100644 index d5e170a1100..00000000000 --- a/test/jdk/java/util/logging/TestUILoggerContext.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (c) 2013, 2024, 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.EnumSet; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/* - * @test - * @bug 8017174 8010727 8019945 - * @summary NPE when using Logger.getAnonymousLogger or - * LogManager.getLogManager().getLogger - * - * @modules java.base/jdk.internal.access - * java.logging - * @run main/othervm TestUILoggerContext LoadingUIContext - * @run main/othervm TestUILoggerContext LoadingMain - * @run main/othervm TestUILoggerContext One - * @run main/othervm TestUILoggerContext Two - * @run main/othervm TestUILoggerContext Three - * @run main/othervm TestUILoggerContext Four - * @run main/othervm TestUILoggerContext Five - * @run main/othervm TestUILoggerContext Six - * @run main/othervm TestUILoggerContext Seven - * @run main/othervm TestUILoggerContext - */ - -// NOTE: We run in other VM in order to cause LogManager class to be loaded anew. -public class TestUILoggerContext { - - // The bridge class initializes the logging system. - // It stubs the UI context in order to simulate context changes. - // - public static class Bridge { - - private static class JavaAWTAccessStub implements JavaAWTAccess { - boolean active = true; - - private static class TestExc { - private final Map map = new HashMap<>(); - void put(Object key, Object v) { map.put(key, v); } - Object get(Object key) { return map.get(key); } - void remove(Object o) { map.remove(o); } - public static TestExc exc(Object o) { - return TestExc.class.cast(o); - } - } - - TestExc exc; - - @Override - public Object getAppletContext() { return active ? exc : null; } - } - - static final JavaAWTAccessStub javaAwtAccess = new JavaAWTAccessStub(); - public static void init() { - SharedSecrets.setJavaAWTAccess(javaAwtAccess); - } - - public static void changeContext() { - System.out.println("... Switching to a new UI context ..."); - javaAwtAccess.active = true; - javaAwtAccess.exc = new JavaAWTAccessStub.TestExc(); - } - - public static void desactivate() { - System.out.println("... Running with no UI context ..."); - javaAwtAccess.exc = null; - javaAwtAccess.active = false; - } - - public static class CustomAnonymousLogger extends Logger { - public CustomAnonymousLogger() { - this(""); - } - public CustomAnonymousLogger(String name) { - super(null, null); - System.out.println( " LogManager: " +LogManager.getLogManager()); - System.out.println( " getLogger: " +LogManager.getLogManager().getLogger(name)); - setParent(LogManager.getLogManager().getLogger(name)); - } - } - - public static class CustomLogger extends Logger { - CustomLogger(String name) { - super(name, null); - } - } - } - - public static enum TestCase { - LoadingUIContext, LoadingMain, One, Two, Three, Four, Five, Six, Seven; - public void test() { - switch(this) { - // When run - each of these two tests must be - // run before any other tests and before each other. - case LoadingUIContext: testLoadingUIContext(); break; - case LoadingMain: testLoadingMain(); break; - case One: testOne(); break; - case Two: testTwo(); break; - case Three: testThree(); break; - case Four: testFour(); break; - case Five: testFive(); break; - case Six: testSix(); break; - case Seven: testSeven(); break; - } - } - public String describe() { - switch(this) { - case LoadingUIContext: - return "Test that when the LogManager class is" - + " loaded with UI context first," - + "\n all LoggerContexts are correctly initialized"; - case LoadingMain: - return "Test that when the LogManager class is" - + " loaded in the main thread first," - + "\n all LoggerContexts are correctly initialized"; - case One: - return "Test that Logger.getAnonymousLogger()" - + " and new CustomAnonymousLogger() don't throw NPE"; - case Two: - return "Test that Logger.getLogger(\"\")" - + " does not return null nor throws NPE"; - case Three: - return "Test that LogManager.getLogManager().getLogger(\"\")" - + " does not return null nor throws NPE"; - case Four: - return "Test that Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)" - + " does not return null,\n and that" - + " new CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME)" - + " does not throw NPE"; - case Five: - return "Test that LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME)" - + "\n does not return null nor throws NPE"; - case Six: - return "Test that manager.getLogger(Logger.GLOBAL_LOGGER_NAME)" - + " returns null\n when manager is not the default" - + " LogManager instance.\n" - + "Test adding a new logger named \"global\" in that" - + " non default instance."; - case Seven: return "Test that manager.getLogger(\"\")" - + " returns null\n when manager is not the default" - + " LogManager instance.\n" - + "Test adding a new logger named \"\" in that" - + " non default instance."; - default: return "Undefined"; - } - } - }; - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - Bridge.init(); - EnumSet tests = EnumSet.noneOf(TestCase.class); - for (String arg : args) { - tests.add(TestCase.valueOf(arg)); - } - if (args.length == 0) { - tests = EnumSet.complementOf(EnumSet.of(TestCase.LoadingMain)); - } - final EnumSet loadingTests = - EnumSet.of(TestCase.LoadingUIContext, TestCase.LoadingMain); - int testrun = 0; - for (TestCase test : tests) { - if (loadingTests.contains(test)) { - if (testrun > 0) { - throw new UnsupportedOperationException("Test case " - + test + " must be executed first!"); - } - } - System.out.println("Testing "+ test+": "); - System.out.println(test.describe()); - try { - test.test(); - } catch (Exception x) { - throw new Error(String.valueOf(test) - + "failed: "+x+"\n "+"FAILED: "+test.describe()+"\n", x); - } finally { - testrun++; - } - Bridge.changeContext(); - System.out.println("PASSED: "+ test); - } - } - - public static void testLoadingUIContext() { - Bridge.changeContext(); - - Logger bar = new Bridge.CustomLogger("com.foo.Bar"); - LogManager.getLogManager().addLogger(bar); - assertNotNull(bar.getParent()); - testParent(bar); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(bar.getName())); - - Bridge.desactivate(); - - Logger foo = new Bridge.CustomLogger("com.foo.Foo"); - boolean b = LogManager.getLogManager().addLogger(foo); - assertEquals(Boolean.TRUE, Boolean.valueOf(b)); - assertNotNull(foo.getParent()); - testParent(foo); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(foo.getName())); - } - - public static void testLoadingMain() { - Bridge.desactivate(); - - Logger bar = new Bridge.CustomLogger("com.foo.Bar"); - LogManager.getLogManager().addLogger(bar); - assertNotNull(bar.getParent()); - testParent(bar); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(bar.getName())); - - Bridge.changeContext(); - - Logger foo = new Bridge.CustomLogger("com.foo.Foo"); - boolean b = LogManager.getLogManager().addLogger(foo); - assertEquals(Boolean.TRUE, Boolean.valueOf(b)); - assertNotNull(foo.getParent()); - testParent(foo); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(foo.getName())); - - } - - public static void testOne() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getAnonymousLogger(); - Logger logger1b = Logger.getAnonymousLogger(); - Bridge.changeContext(); - Logger logger2 = Logger.getAnonymousLogger(); - Logger logger2b = Logger.getAnonymousLogger(); - Bridge.changeContext(); - Logger logger3 = new Bridge.CustomAnonymousLogger(); - Logger logger3b = new Bridge.CustomAnonymousLogger(); - Bridge.changeContext(); - Logger logger4 = new Bridge.CustomAnonymousLogger(); - Logger logger4b = new Bridge.CustomAnonymousLogger(); - } - } - - - public static void testTwo() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getLogger(""); - Logger logger1b = Logger.getLogger(""); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - Logger logger2 = Logger.getLogger(""); - Logger logger2b = Logger.getLogger(""); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - assertEquals(logger1, logger2); - } - } - - public static void testThree() { - for (int i=0; i<3 ; i++) { - Logger logger1 = LogManager.getLogManager().getLogger(""); - Logger logger1b = LogManager.getLogManager().getLogger(""); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - Logger logger2 = LogManager.getLogManager().getLogger(""); - Logger logger2b = LogManager.getLogManager().getLogger(""); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - assertEquals(logger1, logger2); - } - } - - public static void testFour() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - - Logger logger2 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - - assertEquals(logger1, logger2); - - Bridge.changeContext(); - Logger logger3 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger3b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Bridge.changeContext(); - Logger logger4 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger4b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - } - } - - public static void testFive() { - for (int i=0; i<3 ; i++) { - Logger logger1 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - - Bridge.changeContext(); - - Logger logger2 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - - assertEquals(logger1, logger2); - } - } - - /** - * This test is designed to test the behavior of additional LogManager instances. - * It must be noted that if the security manager is off, then calling - * Bridge.changeContext() has actually no effect. - * off. - **/ - public static void testSix() { - for (int i=0; i<3 ; i++) { - Bridge.desactivate(); - LogManager manager = new LogManager() {}; - Logger logger1 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNull(logger1); - assertNull(logger1b); - Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global); - Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, global); - assertEquals(logger2b, global); - assertNull(manager.getLogger("")); - assertNull(manager.getLogger("")); - - for (int j = 0; j<3; j++) { - Bridge.changeContext(); - - // this is not a supported configuration: - // We are in an UI context with several log managers. - // We however need to check our assumptions... - - // UI context => root logger and global logger should also be null. - - Logger expected = global; - Logger logger3 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger3b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertEquals(expected, logger3); - assertEquals(expected, logger3b); - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); - Logger logger4 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger4b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger4); - assertNotNull(logger4b); - expected = global; - assertEquals(logger4, expected); - assertEquals(logger4b, expected); - - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = null; - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); - } - - } - } - - /** - * This test is designed to test the behavior of additional LogManager instances. - * It must be noted that if the security manager is off, then calling - * Bridge.changeContext() has actually no effect. - **/ - public static void testSeven() { - for (int i=0; i<3 ; i++) { - Bridge.desactivate(); - LogManager manager = new LogManager() {}; - Logger logger1 = manager.getLogger(""); - Logger logger1b = manager.getLogger(""); - assertNull(logger1); - assertNull(logger1b); - Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global); - Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, global); - assertEquals(logger2b, global); - Logger logger3 = manager.getLogger(""); - Logger logger3b = manager.getLogger(""); - assertNull(logger3); - assertNull(logger3b); - Logger root = new Bridge.CustomLogger(""); - manager.addLogger(root); - Logger logger4 = manager.getLogger(""); - Logger logger4b = manager.getLogger(""); - assertNotNull(logger4); - assertNotNull(logger4b); - assertEquals(logger4, root); - assertEquals(logger4b, root); - - for (int j = 0 ; j < 3 ; j++) { - Bridge.changeContext(); - - // this is not a supported configuration: - // We are in an UI context with several log managers. - // We however need to check our assumptions... - - // UI context => root logger and global logger should also be null. - - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = root; - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); - - assertEquals(global, manager.getLogger(Logger.GLOBAL_LOGGER_NAME)); - - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); - Logger logger6 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger6b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger expectedGlobal = global; - - assertNotNull(logger6); - assertNotNull(logger6b); - assertEquals(logger6, expectedGlobal); - assertEquals(logger6b, expectedGlobal); - assertEquals(root, manager.getLogger("")); - - Logger root2 = new Bridge.CustomLogger(""); - manager.addLogger(root2); - expectedRoot = root; - Logger logger7 = manager.getLogger(""); - Logger logger7b = manager.getLogger(""); - assertNotNull(logger7); - assertNotNull(logger7b); - assertEquals(logger7, expectedRoot); - assertEquals(logger7b, expectedRoot); - } - } - } - - public static void testParent(Logger logger) { - Logger l = logger; - while (l.getParent() != null) { - l = l.getParent(); - } - assertEquals("", l.getName()); - } - - public static class TestError extends RuntimeException { - public TestError(String msg) { - super(msg); - } - } - - public static void assertNotNull(Object obj) { - if (obj == null) throw new NullPointerException(); - } - - public static void assertNull(Object obj) { - if (obj != null) throw new TestError("Null expected, got "+obj); - } - - public static void assertEquals(Object o1, Object o2) { - if (o1 != o2) { - throw new TestError(o1 + " != " + o2); - } - } - - public static void assertNotEquals(Object o1, Object o2) { - if (o1 == o2) { - throw new TestError(o1 + " == " + o2); - } - } -}