1/*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26import java.lang.reflect.Method;
27import java.lang.System.Logger;
28import java.util.ResourceBundle;
29import java.util.ListResourceBundle;
30
31/*
32 * Tests when logger client is in Xbootclasspath
33 */
34public final class BootClient {
35
36    public static void main(String[] args) throws Exception {
37        assertTrue(args.length >= 2);
38        String loggerMode = args[0];
39        String loggerClassName = args[1];
40        String underlyingLoggerClassName = args.length >= 3 ? args[2] : null;
41
42        testLogger(loggerMode, loggerClassName, underlyingLoggerClassName);
43        testLog(underlyingLoggerClassName);
44    }
45
46    /*
47     * Tests System.getLogger(String) get expected logger.
48     */
49    private static void testLogger(String loggerMode, String loggerClassName,
50                                   String underlyingLoggerClassName) {
51        String name = "test.boot";
52        Logger logger = getLogger(name);
53        printLogger(logger);
54
55        final Module lm = logger.getClass().getModule();
56        final ClassLoader loggerCL = lm.getClassLoader();
57        if (loggerMode.equals("system")) {
58            assertTrue(lm.isNamed());
59            assertTrue(loggerCL == null);
60        } else if(loggerMode.equals("unnamed")) {
61            assertTrue(!lm.isNamed());
62            assertTrue(loggerCL != null);
63        } else {
64            throw new RuntimeException("wrong parameter");
65        }
66
67        assertTrue(loggerClassName.equals(logger.getClass().getName()));
68        if (underlyingLoggerClassName != null) {
69            String loggerName = logger.getName();
70            if (underlyingLoggerClassName.equals(
71                    "sun.util.logging.internal.LoggingProviderImpl$JULWrapper")) {
72                assertTrue(loggerName.equals(name));
73            } else {
74                assertTrue(loggerName.equals(underlyingLoggerClassName));
75            }
76        }
77    }
78
79    /*
80     * Tests Logger retrieved by System.getLogger(String, ResourceBundle) and
81     * System.getLogger(String) works well.
82     */
83    private static void testLog(String underlyingLoggerClassName) throws Exception {
84        if (underlyingLoggerClassName == null) {
85            return;
86        }
87
88        if (underlyingLoggerClassName.equals("pkg.a.l.LoggerA")
89                || underlyingLoggerClassName.equals("pkg.b.l.LoggerB")) {
90
91            String name = "test.boot.logger";
92            String plainMsg = "this is test log message #1";
93            ResourceBundle rb = new MyResourcesBoot();
94            Throwable ex = new Throwable("this is an expected exception to be logged");
95            Class<?> clazz = Class.forName(underlyingLoggerClassName);
96            Method method = clazz.getMethod("checkLog", String.class,
97                                            System.Logger.Level.class,
98                                            ResourceBundle.class, String.class,
99                                            Throwable.class, Object[].class);
100
101            Logger logger = getLogger(name);
102            printLogger(logger);
103            assertTrue(logger.getClass().getName()
104                             .equals("jdk.internal.logger.LazyLoggers$JdkLazyLogger"));
105            assertTrue(logger.getName().equals(underlyingLoggerClassName));
106            logger.log(Logger.Level.WARNING, plainMsg);
107            boolean pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
108                                                  null, plainMsg, ex, (Object)null);
109            assertTrue(pass);
110            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
111                                          rb, MyResourcesBoot.VALUE, (Throwable)null,
112                                          (Object)null);
113            assertTrue(!pass);
114
115            logger = getLogger(name, rb);
116            printLogger(logger);
117            assertTrue(logger.getClass().getName()
118                             .equals("jdk.internal.logger.LocalizedLoggerWrapper"));
119            assertTrue(logger.getName().equals(underlyingLoggerClassName));
120            logger.log(Logger.Level.INFO, MyResourcesBoot.KEY);
121            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
122                                          rb, MyResourcesBoot.VALUE, (Throwable)null,
123                                          (Object)null);
124            assertTrue(pass);
125            pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
126                                          null, plainMsg, ex, (Object)null);
127            assertTrue(pass);
128        }
129    }
130
131    private static class MyResourcesBoot extends ListResourceBundle {
132        static final String KEY = "this is the key in MyResourcesBoot";
133        static final String VALUE = "THIS IS THE VALUE IN MyResourcesBoot";
134
135        @Override
136        protected Object[][] getContents() {
137            return new Object[][] {
138                {KEY, VALUE}
139            };
140        }
141    }
142
143    private static Logger getLogger(String name) {
144        return BootUsage.getLogger(name);
145    }
146
147    private static Logger getLogger(String name, ResourceBundle rb) {
148        return BootUsage.getLogger(name, rb);
149    }
150
151    private static void printLogger(Logger logger) {
152        System.err.println("logger name: " + logger.getName()
153                           + ", logger class: " + logger.getClass());
154    }
155
156    private static void assertTrue(boolean b) {
157        if (!b) {
158            throw new RuntimeException("expected true, but get false.");
159        }
160    }
161}
162