Skip to content

Commit

Permalink
Merge pull request #160 from dmlloyd/java9-and-modules
Browse files Browse the repository at this point in the history
Java 9 and modules related changes
  • Loading branch information
jamezp authored Dec 7, 2017
2 parents 72a880d + d1ac66f commit 27ed721
Show file tree
Hide file tree
Showing 12 changed files with 677 additions and 458 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<version.javax.json>1.0</version.javax.json>
<version.org.byteman>3.0.10</version.org.byteman>
<version.org.glassfish.javax.json>1.0.4</version.org.glassfish.javax.json>
<version.org.jboss.modules.jboss-modules>1.5.2.Final</version.org.jboss.modules.jboss-modules>
<version.org.jboss.modules.jboss-modules>1.6.2.Final</version.org.jboss.modules.jboss-modules>
<version.org.wildfly.common.wildfly-common>1.2.0.Final</version.org.wildfly.common.wildfly-common>
<version.junit.junit>4.12</version.junit.junit>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,6 @@ public CallerClassLoaderLogContextSelector(final boolean checkParentClassLoaders
this(LogContext.DEFAULT_LOG_CONTEXT_SELECTOR, checkParentClassLoaders);
}

private static final class Gateway extends SecurityManager {
protected Class[] getClassContext() {
return super.getClassContext();
}
}

private static final Gateway GATEWAY;

static {
GATEWAY = AccessController.doPrivileged(new PrivilegedAction<Gateway>() {
public Gateway run() {
return new Gateway();
}
});
}

private final LogContextSelector defaultSelector;

private final ConcurrentMap<ClassLoader, LogContext> contextMap = new CopyOnWriteMap<ClassLoader, LogContext>();
Expand All @@ -110,32 +94,20 @@ public Gateway run() {

private final PrivilegedAction<LogContext> logContextAction = new PrivilegedAction<LogContext>() {
public LogContext run() {
for (Class<?> caller : GATEWAY.getClassContext()) {
final ClassLoader classLoader = caller.getClassLoader();
// If the class loader is a log API class loader or null (bootstrap class loader), keep checking
if (classLoader == null || logApiClassLoaders.contains(classLoader)) {
continue;
}
final LogContext result = check(classLoader);
if (result != null) {
return result;
}
break;
}
return defaultSelector.getLogContext();
final Class<?> callingClass = JDKSpecific.findCallingClass(logApiClassLoaders);
return callingClass == null ? defaultSelector.getLogContext() : check(callingClass.getClassLoader());
}

private LogContext check(final ClassLoader classLoader) {
if (classLoader != null && !logApiClassLoaders.contains(classLoader)) {
final LogContext context = contextMap.get(classLoader);
if (context != null) {
return context;
}
if (checkParentClassLoaders) {
return check(classLoader.getParent());
}
final LogContext context = contextMap.get(classLoader);
if (context != null) {
return context;
}
return null;
final ClassLoader parent = classLoader.getParent();
if (parent != null && checkParentClassLoaders && ! logApiClassLoaders.contains(parent)) {
return check(parent);
}
return defaultSelector.getLogContext();
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,6 @@ public ClassLoaderLogContextSelector(final boolean checkParentClassLoaders) {
this(LogContext.DEFAULT_LOG_CONTEXT_SELECTOR, checkParentClassLoaders);
}

private static final class Gateway extends SecurityManager {
protected Class[] getClassContext() {
return super.getClassContext();
}
}

private static final Gateway GATEWAY;

static {
GATEWAY = AccessController.doPrivileged(new PrivilegedAction<Gateway>() {
public Gateway run() {
return new Gateway();
}
});
}

private final LogContextSelector defaultSelector;

private final ConcurrentMap<ClassLoader, LogContext> contextMap = new CopyOnWriteMap<ClassLoader, LogContext>();
Expand All @@ -105,27 +89,20 @@ public Gateway run() {

private final PrivilegedAction<LogContext> logContextAction = new PrivilegedAction<LogContext>() {
public LogContext run() {
for (Class<?> caller : GATEWAY.getClassContext()) {
final ClassLoader classLoader = caller.getClassLoader();
final LogContext result = check(classLoader);
if (result != null) {
return result;
}
}
return defaultSelector.getLogContext();
final Class<?> callingClass = JDKSpecific.findCallingClass(logApiClassLoaders);
return callingClass == null ? defaultSelector.getLogContext() : check(callingClass.getClassLoader());
}

private LogContext check(final ClassLoader classLoader) {
if (classLoader != null && !logApiClassLoaders.contains(classLoader)) {
final LogContext context = contextMap.get(classLoader);
if (context != null) {
return context;
}
if (checkParentClassLoaders) {
return check(classLoader.getParent());
}
final LogContext context = contextMap.get(classLoader);
if (context != null) {
return context;
}
return null;
final ClassLoader parent = classLoader.getParent();
if (parent != null && checkParentClassLoaders && ! logApiClassLoaders.contains(parent)) {
return check(parent);
}
return defaultSelector.getLogContext();
}
};

Expand Down
72 changes: 51 additions & 21 deletions src/main/java/org/jboss/logmanager/ExtLogRecord.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ public static ExtLogRecord wrap(LogRecord rec) {
private String hostName;
private String processName;
private long processId = -1;
private String sourceModuleName;
private String sourceModuleVersion;

private void writeObject(ObjectOutputStream oos) throws IOException {
copyAll();
Expand All @@ -174,6 +176,8 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound
hostName = (String) fields.get("hostName", null);
processName = (String) fields.get("processName", null);
processId = fields.get("processId", -1L);
sourceModuleName = (String) fields.get("sourceModuleName", null);
sourceModuleVersion = (String) fields.get("sourceModuleVersion", null);
}

/**
Expand Down Expand Up @@ -326,30 +330,16 @@ private void calculateCaller() {
return;
}
calculateCaller = false;
final StackTraceElement[] stack = new Throwable().getStackTrace();
boolean found = false;
for (StackTraceElement element : stack) {
final String className = element.getClassName();
if (found) {
if (! loggerClassName.equals(className)) {
setSourceClassName(className);
setSourceMethodName(element.getMethodName());
setSourceLineNumber(element.getLineNumber());
setSourceFileName(element.getFileName());
return;
}
} else {
found = loggerClassName.equals(className);
}
}
setUnknownCaller();
JDKSpecific.calculateCaller(this);
}

private void setUnknownCaller() {
setSourceClassName("<unknown>");
setSourceMethodName("<unknown>");
void setUnknownCaller() {
setSourceClassName(null);
setSourceMethodName(null);
setSourceLineNumber(-1);
setSourceFileName("<unknown>");
setSourceFileName(null);
setSourceModuleName(null);
setSourceModuleVersion(null);
}

/**
Expand Down Expand Up @@ -426,6 +416,46 @@ public void setSourceMethodName(final String sourceMethodName) {
super.setSourceMethodName(sourceMethodName);
}

/**
* Get the name of the module that initiated the logging request, if known.
*
* @return the name of the module that initiated the logging request
*/
public String getSourceModuleName() {
calculateCaller();
return sourceModuleName;
}

/**
* Set the source module name of this record.
*
* @param sourceModuleName the source module name
*/
public void setSourceModuleName(final String sourceModuleName) {
calculateCaller = false;
this.sourceModuleName = sourceModuleName;
}

/**
* Get the version of the module that initiated the logging request, if known.
*
* @return the version of the module that initiated the logging request
*/
public String getSourceModuleVersion() {
calculateCaller();
return sourceModuleVersion;
}

/**
* Set the source module version of this record.
*
* @param sourceModuleVersion the source module version
*/
public void setSourceModuleVersion(final String sourceModuleVersion) {
calculateCaller = false;
this.sourceModuleVersion = sourceModuleVersion;
}

/**
* Get the fully formatted log record, with resources resolved and parameters applied.
*
Expand Down
120 changes: 120 additions & 0 deletions src/main/java/org/jboss/logmanager/JDKSpecific.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* 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.AccessController;
import java.security.PrivilegedAction;
import java.util.Set;

import org.jboss.modules.Module;
import org.jboss.modules.Version;

/**
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
final class JDKSpecific {
private JDKSpecific() {}

private static final Gateway GATEWAY;
private static final boolean JBOSS_MODULES;

static {
GATEWAY = AccessController.doPrivileged(new PrivilegedAction<Gateway>() {
public Gateway run() {
return new Gateway();
}
});
boolean jbossModules = false;
try {
Module.getStartTime();
jbossModules = true;
} catch (Throwable ignored) {}
JBOSS_MODULES = jbossModules;
}

static final class Gateway extends SecurityManager {
protected Class<?>[] getClassContext() {
return super.getClassContext();
}
}

static Class<?> findCallingClass(Set<ClassLoader> rejectClassLoaders) {
for (Class<?> caller : GATEWAY.getClassContext()) {
final ClassLoader classLoader = caller.getClassLoader();
if (classLoader != null && ! rejectClassLoaders.contains(classLoader)) {
return caller;
}
}
return null;
}

static void calculateCaller(ExtLogRecord logRecord) {
final String loggerClassName = logRecord.getLoggerClassName();
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
final Class<?>[] classes = GATEWAY.getClassContext();
// The stack trace may be missing classes, but the class context is not, so if we find a mismatch, we skip the class context items.
int i = 1, j = 0;
Class<?> clazz = classes[i++];
StackTraceElement element = stackTrace[j++];
boolean found = false;
for (;;) {
if (clazz.getName().equals(element.getClassName())) {
if (clazz.getName().equals(loggerClassName)) {
// next entry could be the one we want!
found = true;
} else {
if (found) {
logRecord.setSourceClassName(element.getClassName());
logRecord.setSourceMethodName(element.getMethodName());
logRecord.setSourceFileName(element.getFileName());
logRecord.setSourceLineNumber(element.getLineNumber());
if (JBOSS_MODULES) {
calculateModule(logRecord, clazz);
}
return;
}
}
if (j == classes.length) {
logRecord.setUnknownCaller();
return;
}
element = stackTrace[j ++];
}
if (i == classes.length) {
logRecord.setUnknownCaller();
return;
}
clazz = classes[i ++];
}
}

private 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);
}
}
}
}
Loading

0 comments on commit 27ed721

Please sign in to comment.