[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