/*
 * 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.logging.Logger;
import sun.awt.AppContext;
import sun.awt.SunToolkit;


/**
 * @test
 * @bug 8026404
 * @summary checks that calling getLogger() from a Thread whose ThreadGroup is
 *          a child of the main root group doesn't throw an exception.
 * @modules java.desktop/sun.awt
 *          java.logging
 * @build TestMainAppContext
 * @run main/othervm TestMainAppContext
 * @author danielfuchs
 */
public class TestMainAppContext {

    static volatile Throwable thrown = null;

    public static void main(String... args) throws Exception {
        ThreadGroup rootTG = Thread.currentThread().getThreadGroup();
        while (rootTG.getParent() != null) {
            rootTG = rootTG.getParent();
        }

        ThreadGroup tg = new ThreadGroup(rootTG, "main");
        final Thread t1 = new Thread(tg, "child") {
            @Override
            public void run() {
                try {
                    AppContext context = SunToolkit.createNewAppContext();
                } catch(Throwable t) {
                    thrown = t;
                }
            }
        };
        t1.start();
        t1.join();
        if (thrown != null) {
            throw new RuntimeException("Unexpected exception: " + thrown, thrown);
        }
        Thread t2 = new Thread(tg, "BugDetector") {

            @Override
            public void run() {
                try {
                    Logger.getLogger("foo").info("Done");
                } catch (Throwable x) {
                    thrown = x;
                }
            }

        };
        t2.start();
        t2.join();
        if (thrown != null) {
            throw new RuntimeException("Test failed: " + thrown, thrown);
        }
    }

}
