From cfa5545d902c6ea7a103c35dcd8bf390f2c2ea6b Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Fri, 19 Jan 2018 17:05:05 -0600 Subject: [PATCH] [LOGMGR-133] Java 9 integration To test on both Java 8 and Java 9, use this command: mvn clean install -Djava8.home=/path/to/jdk/8 --- pom.xml | 93 ++++++++++- .../org/jboss/logmanager/JDKSpecific.java | 155 ++++++++++++++++++ .../jboss/logmanager/LogLevelInitTask.java | 32 ++++ 3 files changed, 278 insertions(+), 2 deletions(-) create mode 100644 src/main/java9/org/jboss/logmanager/JDKSpecific.java create mode 100644 src/main/java9/org/jboss/logmanager/LogLevelInitTask.java diff --git a/pom.xml b/pom.xml index aa7da8c6..51e2c1d3 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 1.0 3.0.10 1.0.4 - 1.6.2.Final + 1.7.0.Beta3 1.2.0.Final 4.12 @@ -63,6 +63,8 @@ 1.8 1.8 + + 9 @@ -132,10 +134,75 @@ + + + java8-test-profile + + + java8.home + + + + + + maven-surefire-plugin + + + java8-test + test + + test + + + ${java8.home}/bin/java + + ${java8.home}/lib/tools.jar + + + + + + + + + + maven-compiler-plugin + 3.7.0-jboss-1 + + + default-compile + compile + + compile + + + 8 + ${project.build.directory} + ${project.compileSourceRoots} + ${project.build.outputDirectory} + + + + compile-java9 + compile + + compile + + + 9 + ${project.build.directory} + ${project.basedir}/src/main/java9 + ${project.build.directory}/classes/META-INF/versions/9 + + ${project.build.outputDirectory} + + + + maven-source-plugin @@ -148,7 +215,6 @@ -Djdk.attach.allowAttachSelf=true - true org.jboss.logmanager.LogManager ${project.build.directory}${file.separator}logs${file.separator} @@ -160,7 +226,19 @@ ${org.jboss.test.port} ${org.jboss.test.alt.port} + false + + + default-test + + ${project.build.directory}/classes/META-INF/versions/9 + + ${project.build.directory}/classes + + + + maven-enforcer-plugin @@ -171,6 +249,9 @@ ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + true + @@ -178,8 +259,16 @@ org.apache.felix maven-bundle-plugin true + + + biz.aQute.bnd + biz.aQute.bndlib + 3.5.0 + + + <_fixupmessages>"Classes found in the wrong directory";is:=warning ${project.groupId}.*;version=${project.version};-split-package:=error diff --git a/src/main/java9/org/jboss/logmanager/JDKSpecific.java b/src/main/java9/org/jboss/logmanager/JDKSpecific.java new file mode 100644 index 00000000..843f09ca --- /dev/null +++ b/src/main/java9/org/jboss/logmanager/JDKSpecific.java @@ -0,0 +1,155 @@ +package org.jboss.logmanager; + +import static java.security.AccessController.doPrivileged; + +import java.lang.module.ModuleDescriptor; +import java.security.PrivilegedAction; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.jboss.modules.Module; +import org.jboss.modules.Version; + +/** + * @author David M. Lloyd + */ +final class JDKSpecific { + + static final StackWalker WALKER = doPrivileged(new GetStackWalkerAction()); + + private JDKSpecific() {} + + private static final boolean JBOSS_MODULES; + + static { + boolean jbossModules = false; + try { + Module.getStartTime(); + jbossModules = true; + } catch (Throwable ignored) {} + JBOSS_MODULES = jbossModules; + } + + static Class findCallingClass(Set rejectClassLoaders) { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + return doPrivileged(new FindCallingClassAction(rejectClassLoaders)); + } else { + return WALKER.walk(new FindFirstWalkFunction(rejectClassLoaders)); + } + } + + static void calculateCaller(ExtLogRecord logRecord) { + WALKER.walk(new CallerCalcFunction(logRecord)); + } + + static void calculateJdkModule(final ExtLogRecord logRecord, final Class clazz) { + final java.lang.Module module = clazz.getModule(); + if (module != null) { + logRecord.setSourceModuleName(module.getName()); + final ModuleDescriptor descriptor = module.getDescriptor(); + if (descriptor != null) { + final Optional optional = descriptor.version(); + if (optional.isPresent()) { + logRecord.setSourceModuleVersion(optional.get().toString()); + } else { + logRecord.setSourceModuleVersion(null); + } + } + } + } + + static void calculateModule(final ExtLogRecord logRecord, final Class clazz) { + final Module module = Module.forClass(clazz); + if (module != null) { + logRecord.setSourceModuleName(module.getName()); + final Version version = module.getVersion(); + if (version != null) { + logRecord.setSourceModuleVersion(version.toString()); + } else { + logRecord.setSourceModuleVersion(null); + } + } else { + calculateJdkModule(logRecord, clazz); + } + } + + static final class CallerCalcFunction implements Function, Void> { + private final ExtLogRecord logRecord; + + CallerCalcFunction(final ExtLogRecord logRecord) { + this.logRecord = logRecord; + } + + public Void apply(final Stream stream) { + final String loggerClassName = logRecord.getLoggerClassName(); + final Iterator iterator = stream.iterator(); + boolean found = false; + while (iterator.hasNext()) { + final StackWalker.StackFrame frame = iterator.next(); + final Class clazz = frame.getDeclaringClass(); + if (clazz.getName().equals(loggerClassName)) { + // next entry could be the one we want! + found = true; + } else if (found) { + logRecord.setSourceClassName(frame.getClassName()); + logRecord.setSourceMethodName(frame.getMethodName()); + logRecord.setSourceFileName(frame.getFileName()); + logRecord.setSourceLineNumber(frame.getLineNumber()); + if (JBOSS_MODULES) { + calculateModule(logRecord, clazz); + } else { + calculateJdkModule(logRecord, clazz); + } + return null; + } + } + logRecord.setUnknownCaller(); + return null; + } + } + + static final class GetStackWalkerAction implements PrivilegedAction { + GetStackWalkerAction() {} + + public StackWalker run() { + return StackWalker.getInstance(EnumSet.of(StackWalker.Option.RETAIN_CLASS_REFERENCE)); + } + } + + static final class FindCallingClassAction implements PrivilegedAction> { + private final Set rejectClassLoaders; + + FindCallingClassAction(final Set rejectClassLoaders) { + this.rejectClassLoaders = rejectClassLoaders; + } + + public Class run() { + return WALKER.walk(new FindFirstWalkFunction(rejectClassLoaders)); + } + } + + static final class FindFirstWalkFunction implements Function, Class> { + private final Set rejectClassLoaders; + + FindFirstWalkFunction(final Set rejectClassLoaders) { + this.rejectClassLoaders = rejectClassLoaders; + } + + public Class apply(final Stream stream) { + final Iterator iterator = stream.iterator(); + while (iterator.hasNext()) { + final Class clazz = iterator.next().getDeclaringClass(); + final ClassLoader classLoader = clazz.getClassLoader(); + if (! rejectClassLoaders.contains(classLoader)) { + return clazz; + } + } + return null; + } + } +} diff --git a/src/main/java9/org/jboss/logmanager/LogLevelInitTask.java b/src/main/java9/org/jboss/logmanager/LogLevelInitTask.java new file mode 100644 index 00000000..80c0f1b2 --- /dev/null +++ b/src/main/java9/org/jboss/logmanager/LogLevelInitTask.java @@ -0,0 +1,32 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2017 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.PrivilegedAction; + +/** + */ +class LogLevelInitTask implements PrivilegedAction { + LogLevelInitTask() { + } + + public Void run() { + return null; + } +}