/*
 * 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.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.
 * @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, "FakeApplet");
        final Thread t1 = new Thread(tg, "createNewAppContext") {
            @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;
                }
            }

        };

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

    }

}
