[Git][java-team/jboss-logmanager][upstream] New upstream version 2.1.7

Markus Koschany gitlab at salsa.debian.org
Sat Feb 9 11:59:17 GMT 2019


Markus Koschany pushed to branch upstream at Debian Java Maintainers / jboss-logmanager


Commits:
bc07ce72 by Markus Koschany at 2019-02-09T11:54:32Z
New upstream version 2.1.7
- - - - -


13 changed files:

- pom.xml
- + src/main/java/org/jboss/logmanager/JBossLoggerFinder.java
- src/main/java/org/jboss/logmanager/JDKSpecific.java
- + src/main/java/org/jboss/logmanager/Jvm.java
- src/main/java/org/jboss/logmanager/LogLevelInitTask.java
- src/main/java/org/jboss/logmanager/formatters/StructuredFormatter.java
- + src/main/java9/org/jboss/logmanager/JBossLoggerFinder.java
- + src/main/java9/org/jboss/logmanager/Jvm.java
- + src/main/resources/META-INF/services/java.lang.System$LoggerFinder
- src/test/java/org/jboss/logmanager/formatters/StackTraceFormatterTests.java
- + src/test/java9/org/jboss/logmanager/JulLoggingConfigurator.java
- + src/test/java9/org/jboss/logmanager/SystemLoggerMain.java
- + src/test/java9/org/jboss/logmanager/SystemLoggerTests.java


Changes:

=====================================
pom.xml
=====================================
@@ -28,7 +28,7 @@
     <groupId>org.jboss.logmanager</groupId>
     <artifactId>jboss-logmanager</artifactId>
     <packaging>jar</packaging>
-    <version>2.1.5.Final</version>
+    <version>2.1.7.Final</version>
 
     <parent>
         <groupId>org.jboss</groupId>
@@ -155,6 +155,9 @@
                                     <additionalClasspathElements>
                                         <additionalClasspathElement>${java8.home}/lib/tools.jar</additionalClasspathElement>
                                     </additionalClasspathElements>
+                                    <excludes>
+                                        <exclude>org/jboss/logmanager/SystemLoggerTests.java</exclude>
+                                    </excludes>
                                 </configuration>
                             </execution>
                         </executions>
@@ -199,6 +202,18 @@
                             </additionalClasspathElements>
                         </configuration>
                     </execution>
+                    <execution>
+                        <id>test-compile-java9</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                        <configuration>
+                            <release>9</release>
+                            <buildDirectory>${project.build.directory}</buildDirectory>
+                            <compileSourceRoots>${project.basedir}/src/test/java9</compileSourceRoots>
+                        </configuration>
+                    </execution>
                 </executions>
             </plugin>
             <plugin>
@@ -216,7 +231,7 @@
                     <includes>
                         <include>**/*Tests.java</include>
                     </includes>
-                    <argLine>-Djdk.attach.allowAttachSelf=true</argLine>
+                    <argLine>-Djdk.attach.allowAttachSelf=true -Djava.util.logging.manager=org.jboss.logmanager.LogManager</argLine>
                     <systemPropertyVariables>
                         <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                         <test.log.dir>${project.build.directory}${file.separator}logs${file.separator}</test.log.dir>


=====================================
src/main/java/org/jboss/logmanager/JBossLoggerFinder.java
=====================================
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2018 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.logmanager;
+
+/**
+ * For Java 8 this is just an empty type. For Java 9 or greater this implements the {@code System.LoggerFinder}. It
+ * will make an attempt to set the {@code java.util.logging.manager} system property before a logger is accessed.
+ *
+ * @author <a href="mailto:jperkins at redhat.com">James R. Perkins</a>
+ */
+public class JBossLoggerFinder {
+}


=====================================
src/main/java/org/jboss/logmanager/JDKSpecific.java
=====================================
@@ -23,7 +23,6 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Collection;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Set;
 
 import org.jboss.modules.Module;
@@ -33,7 +32,8 @@ import org.jboss.modules.Version;
  * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
  */
 final class JDKSpecific {
-    private JDKSpecific() {}
+    private JDKSpecific() {
+    }
 
     private static final Gateway GATEWAY;
     private static final boolean JBOSS_MODULES;
@@ -48,7 +48,8 @@ final class JDKSpecific {
         try {
             Module.getStartTime();
             jbossModules = true;
-        } catch (Throwable ignored) {}
+        } catch (Throwable ignored) {
+        }
         JBOSS_MODULES = jbossModules;
     }
 
@@ -61,7 +62,7 @@ final class JDKSpecific {
     static Class<?> findCallingClass(Set<ClassLoader> rejectClassLoaders) {
         for (Class<?> caller : GATEWAY.getClassContext()) {
             final ClassLoader classLoader = caller.getClassLoader();
-            if (classLoader != null && ! rejectClassLoaders.contains(classLoader)) {
+            if (classLoader != null && !rejectClassLoaders.contains(classLoader)) {
                 return caller;
             }
         }
@@ -72,7 +73,7 @@ final class JDKSpecific {
         final Collection<Class<?>> result = new LinkedHashSet<>();
         for (Class<?> caller : GATEWAY.getClassContext()) {
             final ClassLoader classLoader = caller.getClassLoader();
-            if (classLoader != null && ! rejectClassLoaders.contains(classLoader)) {
+            if (classLoader != null && !rejectClassLoaders.contains(classLoader)) {
                 result.add(caller);
             }
         }
@@ -88,7 +89,7 @@ final class JDKSpecific {
         Class<?> clazz = classes[i++];
         StackTraceElement element = stackTrace[j++];
         boolean found = false;
-        for (;;) {
+        for (; ; ) {
             if (clazz.getName().equals(element.getClassName())) {
                 if (clazz.getName().equals(loggerClassName)) {
                     // next entry could be the one we want!
@@ -105,17 +106,17 @@ final class JDKSpecific {
                         return;
                     }
                 }
-                if (j == classes.length) {
+                if (j == stackTrace.length) {
                     logRecord.setUnknownCaller();
                     return;
                 }
-                element = stackTrace[j ++];
+                element = stackTrace[j++];
             }
             if (i == classes.length) {
                 logRecord.setUnknownCaller();
                 return;
             }
-            clazz = classes[i ++];
+            clazz = classes[i++];
         }
     }
 


=====================================
src/main/java/org/jboss/logmanager/Jvm.java
=====================================
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2019 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.logmanager;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This is required to be separate from the {@link JDKSpecific} helper. It's specifically required for WildFly embedded
+ * as the {@link JDKSpecific} initializes JBoss Modules which could cause issues if it's initialized too early. This
+ * avoids the early initialization.
+ *
+ * @author <a href="mailto:jperkins at redhat.com">James R. Perkins</a>
+ */
+final class Jvm {
+    private static final boolean MODULAR_JVM;
+
+    static {
+
+        // Get the current Java version and determine, by JVM version level, if this is a modular JDK
+        final String value = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            @Override
+            public String run() {
+                return System.getProperty("java.specification.version");
+            }
+        });
+        // Shouldn't happen, but we'll assume we're not a modular environment
+        boolean modularJvm = false;
+        if (value != null) {
+            final Matcher matcher = Pattern.compile("^(?:1\\.)?(\\d+)$").matcher(value);
+            if (matcher.find()) {
+                modularJvm = Integer.parseInt(matcher.group(1)) >= 9;
+            }
+        }
+        MODULAR_JVM = modularJvm;
+    }
+
+    /**
+     * Determines whether or not this is a modular JVM. The version of the {@code java.specification.version} is checked
+     * to determine if the version is greater than or equal to 9. This is required to disable specific features/hacks
+     * for older JVM's when the log manager is loaded on the boot class path which doesn't support multi-release JAR's.
+     *
+     * @return {@code true} if determined to be a modular JVM, otherwise {@code false}
+     */
+    static boolean isModular() {
+        return MODULAR_JVM;
+    }
+}


=====================================
src/main/java/org/jboss/logmanager/LogLevelInitTask.java
=====================================
@@ -39,6 +39,11 @@ class LogLevelInitTask implements PrivilegedAction<Void> {
 
     @SuppressWarnings({ "unchecked" })
     public Void run() {
+        // If this is a modular JVM ignore the level hack. The check here is required when the log manager is added to
+        // the boot class path. The boot class path does not support multi-release JAR's.
+        if (Jvm.isModular()) {
+            return null;
+        }
         /* This mysterious-looking hack is designed to trick JDK logging into not leaking classloaders and
            so forth when adding levels, by simply shutting down the craptastic level name "registry" that it keeps.
         */


=====================================
src/main/java/org/jboss/logmanager/formatters/StructuredFormatter.java
=====================================
@@ -19,7 +19,6 @@
 
 package org.jboss.logmanager.formatters;
 
-import java.io.PrintWriter;
 import java.io.Writer;
 import java.time.Instant;
 import java.time.ZoneId;
@@ -248,9 +247,9 @@ public abstract class StructuredFormatter extends ExtFormatter {
                 }
 
                 if (isFormattedExceptionOutputType()) {
-                    final StringBuilderWriter w = new StringBuilderWriter();
-                    thrown.printStackTrace(new PrintWriter(w));
-                    generator.add(getKey(Key.STACK_TRACE), w.toString());
+                    final StringBuilder sb = new StringBuilder();
+                    StackTraceFormatter.renderStackTrace(sb, thrown, false, -1);
+                    generator.add(getKey(Key.STACK_TRACE), sb.toString());
                 }
             }
             if (details) {


=====================================
src/main/java9/org/jboss/logmanager/JBossLoggerFinder.java
=====================================
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2018 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.logmanager;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * @author <a href="mailto:jperkins at redhat.com">James R. Perkins</a>
+ */
+public class JBossLoggerFinder extends System.LoggerFinder {
+    private static final Map<System.Logger.Level, java.util.logging.Level> LEVELS = new EnumMap<>(System.Logger.Level.class);
+    private static final AtomicBoolean LOGGED = new AtomicBoolean(false);
+    private static volatile boolean PROPERTY_SET = false;
+
+    static {
+        LEVELS.put(System.Logger.Level.ALL, Level.ALL);
+        LEVELS.put(System.Logger.Level.TRACE, Level.TRACE);
+        LEVELS.put(System.Logger.Level.DEBUG, Level.DEBUG);
+        LEVELS.put(System.Logger.Level.INFO, Level.INFO);
+        LEVELS.put(System.Logger.Level.WARNING, Level.WARN);
+        LEVELS.put(System.Logger.Level.ERROR, Level.ERROR);
+        LEVELS.put(System.Logger.Level.OFF, Level.OFF);
+    }
+
+    @Override
+    public System.Logger getLogger(final String name, final Module module) {
+        if (!PROPERTY_SET) {
+            synchronized (this) {
+                if (!PROPERTY_SET) {
+                    if (System.getSecurityManager() == null) {
+                        if (System.getProperty("java.util.logging.manager") == null) {
+                            System.setProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager");
+                        }
+                    } else {
+                        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                            if (System.getProperty("java.util.logging.manager") == null) {
+                                System.setProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager");
+                            }
+                            return null;
+                        });
+                    }
+                }
+                PROPERTY_SET = true;
+            }
+        }
+        final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(name);
+        if (!(logger instanceof org.jboss.logmanager.Logger)) {
+            if (LOGGED.compareAndSet(false, true)) {
+                logger.log(Level.ERROR, "The LogManager accessed before the \"java.util.logging.manager\" system property was set to \"org.jboss.logmanager.LogManager\". Results may be unexpected.");
+            }
+        }
+        return new JBossSystemLogger(logger);
+    }
+
+    private static class JBossSystemLogger implements System.Logger {
+        private static final String LOGGER_CLASS_NAME = JBossSystemLogger.class.getName();
+        private final java.util.logging.Logger delegate;
+
+        private JBossSystemLogger(final java.util.logging.Logger delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public String getName() {
+            return delegate.getName();
+        }
+
+        @Override
+        public boolean isLoggable(final Level level) {
+            return delegate.isLoggable(LEVELS.getOrDefault(level, java.util.logging.Level.INFO));
+        }
+
+        @Override
+        public void log(final Level level, final ResourceBundle bundle, final String msg, final Throwable thrown) {
+            final ExtLogRecord record = new ExtLogRecord(LEVELS.getOrDefault(level, java.util.logging.Level.INFO), msg, LOGGER_CLASS_NAME);
+            record.setThrown(thrown);
+            record.setResourceBundle(bundle);
+            delegate.log(record);
+        }
+
+        @Override
+        public void log(final Level level, final ResourceBundle bundle, final String format, final Object... params) {
+            final ExtLogRecord record = new ExtLogRecord(LEVELS.getOrDefault(level, java.util.logging.Level.INFO), format, ExtLogRecord.FormatStyle.MESSAGE_FORMAT, LOGGER_CLASS_NAME);
+            record.setParameters(params);
+            record.setResourceBundle(bundle);
+            delegate.log(record);
+        }
+    }
+}


=====================================
src/main/java9/org/jboss/logmanager/Jvm.java
=====================================
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2019 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.logmanager;
+
+/**
+ *
+ * @author <a href="mailto:jperkins at redhat.com">James R. Perkins</a>
+ */
+final class Jvm {
+
+    /**
+     * Always returns {@code true}.
+     *
+     * @return {@code true}
+     */
+    static boolean isModular() {
+        return true;
+    }
+}


=====================================
src/main/resources/META-INF/services/java.lang.System$LoggerFinder
=====================================
@@ -0,0 +1,20 @@
+#
+# JBoss, Home of Professional Open Source.
+#
+# Copyright 2018 Red Hat, Inc., and individual contributors
+# as indicated by the @author tags.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.jboss.logmanager.JBossLoggerFinder


=====================================
src/test/java/org/jboss/logmanager/formatters/StackTraceFormatterTests.java
=====================================
@@ -23,6 +23,7 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 
 import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Test;
 
 /**
@@ -30,6 +31,8 @@ import org.junit.Test;
  */
 public class StackTraceFormatterTests {
 
+    private static final boolean IS_IBM_JDK = System.getProperty("java.vendor").startsWith("IBM");
+
     @Test
     public void compareSimpleStackTrace() {
         final RuntimeException e = new RuntimeException();
@@ -57,6 +60,7 @@ public class StackTraceFormatterTests {
 
     @Test
     public void compareSuppressedAndCauseStackTrace() {
+        Assume.assumeFalse("The IBM JDK does not show print circular references.", IS_IBM_JDK);
         final RuntimeException r1 = new RuntimeException("Exception 1");
         final RuntimeException r2 = new RuntimeException("Exception 2", r1);
         final RuntimeException r3 = new RuntimeException("Exception 3", r2);
@@ -76,6 +80,7 @@ public class StackTraceFormatterTests {
 
     @Test
     public void compareNestedSuppressedStackTrace() {
+        Assume.assumeFalse("The IBM JDK does not show print circular references.", IS_IBM_JDK);
         final RuntimeException r1 = new RuntimeException("Exception 1");
         final RuntimeException r2 = new RuntimeException("Exception 2", r1);
         final RuntimeException r3 = new RuntimeException("Exception 3", r2);
@@ -99,6 +104,7 @@ public class StackTraceFormatterTests {
 
     @Test
     public void compareMultiNestedSuppressedStackTrace() {
+        Assume.assumeFalse("The IBM JDK does not show print circular references.", IS_IBM_JDK);
         final Throwable cause = createMultiNestedCause();
 
         final StringWriter writer = new StringWriter();
@@ -112,6 +118,7 @@ public class StackTraceFormatterTests {
 
     @Test
     public void compareMultiNestedSuppressedAndNestedCauseStackTrace() {
+        Assume.assumeFalse("The IBM JDK does not show print circular references.", IS_IBM_JDK);
         final Throwable rootCause = createMultiNestedCause();
         final RuntimeException cause = new RuntimeException("This is the parent", rootCause);
 


=====================================
src/test/java9/org/jboss/logmanager/JulLoggingConfigurator.java
=====================================
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2018 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.logmanager;
+
+import java.io.FileNotFoundException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.jboss.logmanager.formatters.JsonFormatter;
+import org.jboss.logmanager.handlers.FileHandler;
+
+/**
+ * @author <a href="mailto:jperkins at redhat.com">James R. Perkins</a>
+ */
+public class JulLoggingConfigurator {
+
+    public JulLoggingConfigurator() throws FileNotFoundException {
+        final Logger rootLogger = Logger.getLogger("");
+        final String fileName = System.getProperty("test.log.file.name");
+        final FileHandler handler = new FileHandler(fileName, false);
+        handler.setAutoFlush(true);
+        handler.setFormatter(new JsonFormatter());
+        rootLogger.addHandler(handler);
+        rootLogger.setLevel(Level.INFO);
+    }
+}


=====================================
src/test/java9/org/jboss/logmanager/SystemLoggerMain.java
=====================================
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2018 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.logmanager;
+
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+/**
+ * @author <a href="mailto:jperkins at redhat.com">James R. Perkins</a>
+ */
+public class SystemLoggerMain {
+
+    public static void main(final String[] args) {
+        if (Boolean.getBoolean("system.logger.test.jul")) {
+            // Access the log manager to ensure it's configured before the system property is set
+            LogManager.getLogManager();
+        }
+
+        final System.Logger.Level level = System.Logger.Level.valueOf(System.getProperty("system.logger.test.level", "INFO"));
+        final String msgId = System.getProperty("system.logger.test.msg.id");
+        final String msg = String.format("Test message from %s id %s", SystemLoggerMain.class.getName(), msgId);
+        final System.Logger systemLogger = System.getLogger(SystemLoggerMain.class.getName());
+        MDC.put("logger.type", systemLogger.getClass().getName());
+        MDC.put("java.util.logging.LogManager", LogManager.getLogManager().getClass().getName());
+        MDC.put("java.util.logging.manager", System.getProperty("java.util.logging.manager"));
+        systemLogger.log(level, msg);
+
+        final Logger logger = Logger.getLogger(SystemLoggerMain.class.getName());
+        MDC.put("logger.type", logger.getClass().getName());
+        MDC.put("java.util.logging.LogManager", LogManager.getLogManager().getClass().getName());
+        MDC.put("java.util.logging.manager", System.getProperty("java.util.logging.manager"));
+        logger.info(msg);
+    }
+}


=====================================
src/test/java9/org/jboss/logmanager/SystemLoggerTests.java
=====================================
@@ -0,0 +1,223 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2018 Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.logmanager;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+
+import org.jboss.logmanager.formatters.JsonFormatter;
+import org.jboss.logmanager.handlers.FileHandler;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:jperkins at redhat.com">James R. Perkins</a>
+ */
+public class SystemLoggerTests {
+    private static final boolean WINDOWS = System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win");
+
+    private Path stdout;
+    private Path configFile;
+    private Path logFile;
+
+    @Before
+    public void setup() throws Exception {
+        stdout = Files.createTempFile("stdout", ".txt");
+        logFile = Files.createTempFile("system-logger", ".log");
+        configFile = Files.createTempFile("logging", ".properties");
+    }
+
+    @After
+    public void killProcess() throws IOException {
+        Files.deleteIfExists(stdout);
+        Files.deleteIfExists(logFile);
+        Files.deleteIfExists(configFile);
+    }
+
+    @Test
+    public void testSystemLoggerActivated() throws Exception {
+        createJBossLoggingConfig();
+        final Process process = createProcess("-Dlogging.configuration=" + configFile.toUri().toURL());
+        if (process.waitFor(3L, TimeUnit.SECONDS)) {
+            final int exitCode = process.exitValue();
+            final StringBuilder msg = new StringBuilder("Expected exit value 0 got ")
+                    .append(exitCode);
+            appendStdout(msg);
+            Assert.assertEquals(msg.toString(), 0, exitCode);
+        } else {
+            final Process destroyed = process.destroyForcibly();
+            final StringBuilder msg = new StringBuilder("Failed to exit process within 3 seconds. Exit Code: ")
+                    .append(destroyed.exitValue());
+            appendStdout(msg);
+            Assert.fail(msg.toString());
+        }
+
+        final JsonObject json = readLogFile(logFile);
+        final JsonArray lines = json.getJsonArray("lines");
+        Assert.assertEquals(2, lines.size());
+        // The first line should be from a SystemLogger
+        JsonObject line = lines.getJsonObject(0);
+        Assert.assertEquals("org.jboss.logmanager.JBossLoggerFinder$JBossSystemLogger", line.getString("loggerClassName"));
+        JsonObject mdc = line.getJsonObject("mdc");
+        Assert.assertEquals("org.jboss.logmanager.JBossLoggerFinder$JBossSystemLogger", mdc.getString("logger.type"));
+        Assert.assertEquals(LogManager.class.getName(), mdc.getString("java.util.logging.LogManager"));
+        Assert.assertEquals(LogManager.class.getName(), mdc.getString("java.util.logging.manager"));
+
+        // The second line should be from a JUL logger
+        line = lines.getJsonObject(1);
+        Assert.assertEquals(Logger.class.getName(), line.getString("loggerClassName"));
+        mdc = line.getJsonObject("mdc");
+        Assert.assertEquals(Logger.class.getName(), mdc.getString("logger.type"));
+        Assert.assertEquals(LogManager.class.getName(), mdc.getString("java.util.logging.LogManager"));
+        Assert.assertEquals(LogManager.class.getName(), mdc.getString("java.util.logging.manager"));
+    }
+
+    @Test
+    public void testSystemLoggerAccessedBeforeActivated() throws Exception {
+        final Process process = createProcess("-Dsystem.logger.test.jul=true", "-Dtest.log.file.name=" + logFile.toString(),
+                "-Djava.util.logging.config.class=" + JulLoggingConfigurator.class.getName());
+        if (process.waitFor(3L, TimeUnit.SECONDS)) {
+            final int exitCode = process.exitValue();
+            final StringBuilder msg = new StringBuilder("Expected exit value 0 got ")
+                    .append(exitCode);
+            appendStdout(msg);
+            Assert.assertEquals(msg.toString(), 0, exitCode);
+        } else {
+            final Process destroyed = process.destroyForcibly();
+            final StringBuilder msg = new StringBuilder("Failed to exit process within 3 seconds. Exit Code: ")
+                    .append(destroyed.exitValue());
+            appendStdout(msg);
+            Assert.fail(msg.toString());
+        }
+
+        final JsonObject json = readLogFile(logFile);
+        final JsonArray lines = json.getJsonArray("lines");
+        Assert.assertEquals(3, lines.size());
+
+        // The first line should be an error indicating the java.util.logging.manager wasn't set before the LogManager
+        // was accessed
+        JsonObject line = lines.getJsonObject(0);
+        Assert.assertEquals("ERROR", line.getString("level"));
+        final String message = line.getString("message");
+        Assert.assertNotNull(message);
+        Assert.assertTrue(message.contains("java.util.logging.manager"));
+
+        // The second line should be from a SystemLogger
+        line = lines.getJsonObject(1);
+        Assert.assertEquals("org.jboss.logmanager.JBossLoggerFinder$JBossSystemLogger", line.getString("loggerClassName"));
+        JsonObject mdc = line.getJsonObject("mdc");
+        Assert.assertEquals("org.jboss.logmanager.JBossLoggerFinder$JBossSystemLogger", mdc.getString("logger.type"));
+        Assert.assertEquals("java.util.logging.LogManager", mdc.getString("java.util.logging.LogManager"));
+
+        // The third line should be from a JUL logger
+        line = lines.getJsonObject(2);
+        Assert.assertEquals("java.util.logging.Logger", line.getString("loggerClassName"));
+        mdc = line.getJsonObject("mdc");
+        Assert.assertEquals("java.util.logging.Logger", mdc.getString("logger.type"));
+        Assert.assertEquals("java.util.logging.LogManager", mdc.getString("java.util.logging.LogManager"));
+    }
+
+    private Process createProcess(final String... javaOpts) throws IOException {
+        final List<String> cmd = new ArrayList<>();
+        cmd.add(findJavaCommand());
+        cmd.add("-ea");
+        cmd.add("--add-modules=java.se");
+        Collections.addAll(cmd, javaOpts);
+        cmd.add("-cp");
+        cmd.add(System.getProperty("java.class.path"));
+        cmd.add(SystemLoggerMain.class.getName());
+        return new ProcessBuilder(cmd)
+                .redirectErrorStream(true)
+                .redirectOutput(stdout.toFile())
+                .start();
+    }
+
+    private void createJBossLoggingConfig() throws IOException {
+        final Properties properties = new Properties();
+
+        properties.setProperty("logger.level", "INFO");
+        properties.setProperty("logger.handlers", "FILE");
+
+        properties.setProperty("handler.FILE", FileHandler.class.getName());
+        properties.setProperty("handler.FILE.formatter", "JSON");
+        properties.setProperty("handler.FILE.level", "INFO");
+        properties.setProperty("handler.FILE.properties", "autoFlush,append,fileName");
+        properties.setProperty("handler.FILE.constructorProperties", "fileName,append");
+        properties.setProperty("handler.FILE.append", "false");
+        properties.setProperty("handler.FILE.fileName", logFile.toString());
+
+        properties.setProperty("formatter.JSON", JsonFormatter.class.getName());
+
+        try (BufferedWriter writer = Files.newBufferedWriter(configFile, StandardCharsets.UTF_8)) {
+            properties.store(writer, "Test logging properties");
+        }
+    }
+
+    private void appendStdout(final StringBuilder builder) throws IOException {
+        for (String line : Files.readAllLines(stdout)) {
+            builder.append(System.lineSeparator())
+                    .append(line);
+        }
+    }
+
+    private static JsonObject readLogFile(final Path logFile) throws IOException {
+        final JsonArrayBuilder builder = Json.createArrayBuilder();
+        try (BufferedReader reader = Files.newBufferedReader(logFile, StandardCharsets.UTF_8)) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                try (JsonReader jsonReader = Json.createReader(new StringReader(line))) {
+                    builder.add(jsonReader.read());
+                }
+            }
+        }
+        return Json.createObjectBuilder().add("lines", builder).build();
+    }
+
+    private static String findJavaCommand() {
+        String javaHome = System.getProperty("java.home");
+        if (javaHome != null) {
+            String exe = "java";
+            if (WINDOWS) {
+                exe = "java.exe";
+            }
+            return Paths.get(javaHome, "bin", exe).toAbsolutePath().toString();
+        }
+        return "java";
+    }
+}
\ No newline at end of file



View it on GitLab: https://salsa.debian.org/java-team/jboss-logmanager/commit/bc07ce72a14b646adf52a0167aa22a5f8bffc2a5

-- 
View it on GitLab: https://salsa.debian.org/java-team/jboss-logmanager/commit/bc07ce72a14b646adf52a0167aa22a5f8bffc2a5
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190209/a2fce3e6/attachment.html>


More information about the pkg-java-commits mailing list