Commit 34552d7d authored by Ralph Goers's avatar Ralph Goers
Browse files

LOG4J2-1359 - Set up for modules. Do not use multi-release jars

parent 311101cb
release-2.x CVE-creation-process GenericMapMessage GenericMapMessageSimple LOG4J2-1694 LOG4J2-1888 LOG4J2-1889 LOG4J2-1949 LOG4J2-1986-b LOG4J2-2163 LOG4J2-2266 LOG4J2-2621 LOG4J2-2644-2.x LOG4J2-2829 LOG4J2-2948 LOG4J2-2993 LOG4J2-3003 LOG4J2-3004 LOG4J2-3020 LOG4J2-3051 LOG4J2-3056 LOG4J2-3075 LOG4J2-3080 LOG4J2-3116 LOG4J2-3185 LOG4J2-3301 LOG4J2-3368 LOG4J2-3393 LOG4J2-3644-3.x LOG4J2-913 Lucene5 android api-separation-documentation ckozak/stack_trace_jmh_benchmark dependabot/docker/openjdk-16 dependabot/docker/openjdk-17 dependabot/github_actions/actions/setup-java-2.1.0 dependabot/github_actions/actions/setup-java-2.2.0 dependabot/github_actions/actions/setup-java-2.3.0 dependabot/github_actions/actions/setup-java-2.3.1 dependabot/github_actions/actions/setup-java-2.4.0 dependabot/maven/byteBuddyVersion-1.12.1 dependabot/maven/com.conversantmedia-disruptor-1.2.17 dependabot/maven/com.conversantmedia-disruptor-1.2.19 dependabot/maven/com.github.spotbugs-spotbugs-4.5.0 dependabot/maven/com.github.tomakehurst-wiremock-2.27.1 dependabot/maven/com.github.tomakehurst-wiremock-2.27.2 dependabot/maven/com.h2database-h2-2.0.206 dependabot/maven/com.h2database-h2-2.1.210 dependabot/maven/com.h2database-h2-2.1.212 dependabot/maven/com.sleepycat-je-18.3.12 dependabot/maven/de.flapdoodle.embed-de.flapdoodle.embed.mongo-3.3.1 dependabot/maven/de.flapdoodle.embed-de.flapdoodle.embed.mongo-3.4.5 dependabot/maven/io.fabric8-docker-maven-plugin-0.39.0 dependabot/maven/io.fabric8-kubernetes-client-5.11.2 dependabot/maven/javax.servlet-javax.servlet-api-4.0.1 dependabot/maven/jmh.version-1.34 dependabot/maven/junit-junit-4.13 dependabot/maven/junit-junit-4.13.1 dependabot/maven/log4j-cassandra/org.apache.cassandra-cassandra-all-3.0.26 dependabot/maven/logbackVersion-1.2.10 dependabot/maven/mockitoVersion-4.3.1 dependabot/maven/mongodb3.version-3.12.10 dependabot/maven/mongodb3.version-3.12.5 dependabot/maven/net.javacrumbs.json-unit-json-unit-2.31.0 dependabot/maven/org.apache.activemq-activemq-broker-5.17.0 dependabot/maven/org.apache.activemq-activemq-broker-5.17.1 dependabot/maven/org.apache.commons-commons-compress-1.20 dependabot/maven/org.apache.felix-maven-bundle-plugin-5.1.4 dependabot/maven/org.apache.felix-maven-bundle-plugin-5.1.5 dependabot/maven/org.apache.felix-org.apache.felix.framework-7.0.3 dependabot/maven/org.apache.kafka-kafka-clients-3.0.0 dependabot/maven/org.apache.kafka-kafka-clients-3.1.0 dependabot/maven/org.apache.maven-maven-core-3.6.3 dependabot/maven/org.apache.maven-maven-core-3.8.1 dependabot/maven/org.apache.maven-maven-core-3.8.2 dependabot/maven/org.apache.maven-maven-core-3.8.4 dependabot/maven/org.apache.maven.plugins-maven-checkstyle-plugin-3.1.1 dependabot/maven/org.apache.maven.plugins-maven-checkstyle-plugin-3.1.2 dependabot/maven/org.apache.maven.plugins-maven-pdf-plugin-1.6.0 dependabot/maven/org.apache.maven.plugins-maven-project-info-reports-plugin-3.2.2 dependabot/maven/org.apache.maven.plugins-maven-resources-plugin-3.1.0 dependabot/maven/org.apache.maven.plugins-maven-resources-plugin-3.2.0 dependabot/maven/org.apache.maven.plugins-maven-scm-plugin-1.12.2 dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.2.4 dependabot/maven/org.apache.maven.plugins-maven-site-plugin-3.12.0 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.0 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.10 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.11 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.14 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.2 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.4 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.5 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.6 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.7 dependabot/maven/org.apache.tomcat-tomcat-catalina-10.0.8 dependabot/maven/org.apache.tomcat-tomcat-catalina-9.0.37 dependabot/maven/org.apache.tomcat-tomcat-catalina-9.0.38 dependabot/maven/org.apache.tomcat-tomcat-catalina-9.0.39 dependabot/maven/org.awaitility-awaitility-4.1.1 dependabot/maven/org.codehaus.mojo-build-helper-maven-plugin-3.2.0 dependabot/maven/org.codehaus.mojo-build-helper-maven-plugin-3.3.0 dependabot/maven/org.codehaus.plexus-plexus-compiler-javac-errorprone-2.8.7 dependabot/maven/org.codehaus.plexus-plexus-utils-3.4.1 dependabot/maven/org.eclipse.jetty-jetty-util-9.4.30.v20200611 dependabot/maven/org.eclipse.jetty-jetty-util-9.4.31.v20200723 dependabot/maven/org.jctools-jctools-core-3.0.0 dependabot/maven/org.jctools-jctools-core-3.1.0 dependabot/maven/org.lightcouch-lightcouch-0.2.0 dependabot/maven/org.liquibase-liquibase-core-3.10.3 dependabot/maven/org.liquibase-liquibase-core-4.6.2 dependabot/maven/org.liquibase-liquibase-core-4.7.0 dependabot/maven/org.springframework.ws-spring-ws-core-3.0.10.RELEASE dependabot/maven/org.springframework.ws-spring-ws-core-3.0.9.RELEASE dependabot/maven/org.springframework.ws-spring-ws-core-3.1.1 dependabot/maven/org.springframework.ws-spring-ws-core-3.1.2 dependabot/maven/org.xmlunit-xmlunit-core-2.7.0 dependabot/maven/org.xmlunit-xmlunit-core-2.8.0 dependabot/maven/org.xmlunit-xmlunit-core-2.8.2 dependabot/maven/org.xmlunit-xmlunit-core-2.8.3 dependabot/maven/slf4jVersion-1.7.36 dependabot/maven/spring-boot.version-2.6.0 dependabot/maven/spring-boot.version-2.6.2 dependabot/maven/springVersion-5.2.7.RELEASE dependabot/maven/springVersion-5.2.8.RELEASE dependabot/maven/xmlunitVersion-2.9.0 java9NoMultiRelease jpms-mockito-fails ldap-controls log4j-2.11.1-patches log4j-2.12 log4j-2.17.1-site master master-java11 mean-bean-machine module-compile-fails new-iso-date-time-formats pr/513 release-2.12.x/LOG4J2-3242 revert-276-patch-1 slf4j-2.0 travis-test rel/2.17.2 rel/2.17.1 rel/2.17.0 rel/2.16.0 rel/2.15.0 rel/2.14.1 rel/2.14.0 rel/2.13.3 rel/2.13.2 rel/2.13.1 rel/2.13.0 rel/2.12.4 rel/2.12.3 rel/2.12.2 rel/2.12.1 rel/2.12.0 rel/2.11.2 rel/2.11.1 rel/2.11.0 rel/2.10.0 rel/2.9.0 log4j-2.17.2-rc1 log4j-2.17.1-rc1 log4j-2.17.0-rc1 log4j-2.16.0-rc1 log4j-2.15.1-rc1 log4j-2.15.0-rc2 log4j-2.15.0-rc1 log4j-2.14.1-rc1 log4j-2.14.0-rc1 log4j-2.13.3 log4j-2.13.3-rc1 log4j-2.13.2 log4j-2.13.2-rc1 log4j-2.13.1 log4j-2.13.1-rc2 log4j-2.13.1-rc1 log4j-2.13.0-rc2 log4j-2.13.0-rc1 log4j-2.12.4-rc1 log4j-2.12.3-rc1 log4j-2.12.2-rc1 log4j-2.12.1 log4j-2.12.1-rc1 log4j-2.12.0 log4j-2.12.0-rc2 log4j-2.12.0-rc1 log4j-2.11.2 log4j-2.11.2-rc3 log4j-2.11.2-rc2 log4j-2.11.2-rc1 log4j-2.11.1 log4j-2.11.1-rc1 log4j-2.11.0 log4j-2.11.0-rc1 log4j-2.10.0 log4j-2.10-rc1 log4j-2.9.1-rc1 log4j-2.9.0 log4j-2.9-rc1
No related merge requests found
Showing with 575 additions and 236 deletions
+575 -236
......@@ -39,11 +39,6 @@
<artifactId>org.apache.felix.framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-java9</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
......@@ -84,6 +79,99 @@
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>clean-java9</id>
<goals>
<goal>clean</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>${project.build.directory}/classes</directory>
<includes>
<include>**/*.class</include>
</includes>
<excludes>
<exclude>module-info.class</exclude>
<exclude>**/util/ClassNamePredicate.class</exclude>
<exclude>**/util/ClassPredicate.class</exclude>
<exclude>**/util/StackWalkerStackLocator.class</exclude>
</excludes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Export-Package>org.apache.logging.log4j.*</Export-Package>
<Import-Package>
sun.reflect;resolution:=optional,
org.apache.logging.log4j.core.osgi;resolution:=optional,
org.apache.logging.log4j.core.util;resolution:=optional,
*
</Import-Package>
<Bundle-Activator>org.apache.logging.log4j.util.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<!-- recompile everything for target VM except the module-info.java -->
<configuration>
<excludes>
<exclude>module-info.java</exclude>
<exclude>**/util/ClassNamePredicate.java</exclude>
<exclude>**/util/ClassPredicate.java</exclude>
<exclude>**/util/StackWalkerStackLocator.java</exclude>
</excludes>
<source>1.7</source>
<target>1.7</target>
</configuration>
</execution>
<execution>
<id>process-plugins</id>
<phase>none</phase>
</execution>
<execution>
<id>java9-compile</id>
<goals>
<goal>compile</goal>
</goals>
<phase>process-classes</phase>
<configuration>
<!-- compile everything to ensure module-info contains right entries -->
<!-- required when JAVA_HOME is JDK 8 or below -->
<jdkToolchain>
<version>9</version>
</jdkToolchain>
<release>9</release>
<proc>none</proc>
<includes>
<include>module-info.java</include>
<include>**/util/ClassNamePredicate.java</include>
<include>**/util/ClassPredicate.java</include>
<include>**/util/StackWalkerStackLocator.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
......@@ -108,7 +196,6 @@
<Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
<X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
<X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</archive>
</configuration>
......@@ -151,26 +238,6 @@
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-java9-supplement</id>
<phase>process-classes</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>org.apache.logging.log4j</includeGroupIds>
<includeArtifactIds>log4j-java9</includeArtifactIds>
<excludeTransitive>false</excludeTransitive>
<includes>org/apache/logging/log4j/util/*.class</includes>
<outputDirectory>${project.build.directory}/classes/META-INF/versions/9</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
......
......@@ -32,7 +32,7 @@ import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.apache.logging.log4j.util.ProviderUtil;
import org.apache.logging.log4j.util.ReflectionUtil;
import org.apache.logging.log4j.util.StackLocatorUtil;
import org.apache.logging.log4j.util.Strings;
/**
......@@ -418,7 +418,7 @@ public class LogManager {
* @since 2.4
*/
public static Logger getFormatterLogger() {
return getFormatterLogger(ReflectionUtil.getCallerClass(2));
return getFormatterLogger(StackLocatorUtil.getCallerClass(2));
}
/**
......@@ -449,7 +449,7 @@ public class LogManager {
* @see StringFormatterMessageFactory
*/
public static Logger getFormatterLogger(final Class<?> clazz) {
return getLogger(clazz != null ? clazz : ReflectionUtil.getCallerClass(2),
return getLogger(clazz != null ? clazz : StackLocatorUtil.getCallerClass(2),
StringFormatterMessageFactory.INSTANCE);
}
......@@ -481,7 +481,7 @@ public class LogManager {
* @see StringFormatterMessageFactory
*/
public static Logger getFormatterLogger(final Object value) {
return getLogger(value != null ? value.getClass() : ReflectionUtil.getCallerClass(2),
return getLogger(value != null ? value.getClass() : StackLocatorUtil.getCallerClass(2),
StringFormatterMessageFactory.INSTANCE);
}
......@@ -512,7 +512,7 @@ public class LogManager {
* @see StringFormatterMessageFactory
*/
public static Logger getFormatterLogger(final String name) {
return name == null ? getFormatterLogger(ReflectionUtil.getCallerClass(2)) : getLogger(name,
return name == null ? getFormatterLogger(StackLocatorUtil.getCallerClass(2)) : getLogger(name,
StringFormatterMessageFactory.INSTANCE);
}
......@@ -520,7 +520,7 @@ public class LogManager {
if (clazz != null) {
return clazz;
}
final Class<?> candidate = ReflectionUtil.getCallerClass(3);
final Class<?> candidate = StackLocatorUtil.getCallerClass(3);
if (candidate == null) {
throw new UnsupportedOperationException("No class provided, and an appropriate one cannot be found.");
}
......@@ -534,7 +534,7 @@ public class LogManager {
* @throws UnsupportedOperationException if the calling class cannot be determined.
*/
public static Logger getLogger() {
return getLogger(ReflectionUtil.getCallerClass(2));
return getLogger(StackLocatorUtil.getCallerClass(2));
}
/**
......@@ -576,7 +576,7 @@ public class LogManager {
* @throws UnsupportedOperationException if the calling class cannot be determined.
*/
public static Logger getLogger(final MessageFactory messageFactory) {
return getLogger(ReflectionUtil.getCallerClass(2), messageFactory);
return getLogger(StackLocatorUtil.getCallerClass(2), messageFactory);
}
/**
......@@ -589,7 +589,7 @@ public class LogManager {
* determined.
*/
public static Logger getLogger(final Object value) {
return getLogger(value != null ? value.getClass() : ReflectionUtil.getCallerClass(2));
return getLogger(value != null ? value.getClass() : StackLocatorUtil.getCallerClass(2));
}
/**
......@@ -604,7 +604,7 @@ public class LogManager {
* determined.
*/
public static Logger getLogger(final Object value, final MessageFactory messageFactory) {
return getLogger(value != null ? value.getClass() : ReflectionUtil.getCallerClass(2), messageFactory);
return getLogger(value != null ? value.getClass() : StackLocatorUtil.getCallerClass(2), messageFactory);
}
/**
......@@ -615,7 +615,7 @@ public class LogManager {
* @throws UnsupportedOperationException if {@code name} is {@code null} and the calling class cannot be determined.
*/
public static Logger getLogger(final String name) {
return name != null ? getContext(false).getLogger(name) : getLogger(ReflectionUtil.getCallerClass(2));
return name != null ? getContext(false).getLogger(name) : getLogger(StackLocatorUtil.getCallerClass(2));
}
/**
......@@ -629,7 +629,7 @@ public class LogManager {
*/
public static Logger getLogger(final String name, final MessageFactory messageFactory) {
return name != null ? getContext(false).getLogger(name, messageFactory) : getLogger(
ReflectionUtil.getCallerClass(2), messageFactory);
StackLocatorUtil.getCallerClass(2), messageFactory);
}
/**
......
......@@ -246,7 +246,7 @@ public class MapMessage implements MultiformatMessage, StringBuilderFormattable
public void asXml(final StringBuilder sb) {
sb.append("<Map>\n");
for (int i = 0; i < data.size(); i++) {
sb.append(" <Entry key=\"").append(data.getKeyAt(i)).append("\">").append(data.getValueAt(i))
sb.append(" <Entry key=\"").append(data.getKeyAt(i)).append("\">").append((String)data.getValueAt(i))
.append("</Entry>\n");
}
sb.append("</Map>");
......
......@@ -16,7 +16,6 @@
*/
package org.apache.logging.log4j.util;
import java.lang.reflect.Method;
import java.util.Stack;
import org.apache.logging.log4j.Logger;
......@@ -47,50 +46,12 @@ import org.apache.logging.log4j.status.StatusLogger;
* examination of every virtual frame of execution.
* </p>
*/
public final class ReflectionUtil {
// Checkstyle Suppress: the lower-case 'u' ticks off CheckStyle...
// CHECKSTYLE:OFF
static final int JDK_7u25_OFFSET;
// CHECKSTYLE:OFF
private static final Logger LOGGER = StatusLogger.getLogger();
private static final boolean SUN_REFLECTION_SUPPORTED;
private static final Method GET_CALLER_CLASS;
private static final PrivateSecurityManager SECURITY_MANAGER;
public class DefaultStackLocator implements StackLocator {
static {
Method getCallerClass;
int java7u25CompensationOffset = 0;
try {
final Class<?> sunReflectionClass = LoaderUtil.loadClass("sun.reflect.Reflection");
getCallerClass = sunReflectionClass.getDeclaredMethod("getCallerClass", int.class);
Object o = getCallerClass.invoke(null, 0);
final Object test1 = getCallerClass.invoke(null, 0);
if (o == null || o != sunReflectionClass) {
LOGGER.warn("Unexpected return value from Reflection.getCallerClass(): {}", test1);
getCallerClass = null;
java7u25CompensationOffset = -1;
} else {
o = getCallerClass.invoke(null, 1);
if (o == sunReflectionClass) {
LOGGER.warn("You are using Java 1.7.0_25 which has a broken implementation of "
+ "Reflection.getCallerClass.");
LOGGER.warn("You should upgrade to at least Java 1.7.0_40 or later.");
LOGGER.debug("Using stack depth compensation offset of 1 due to Java 7u25.");
java7u25CompensationOffset = 1;
}
}
} catch (final Exception | LinkageError e) {
LOGGER.info("sun.reflect.Reflection.getCallerClass is not supported. "
+ "ReflectionUtil.getCallerClass will be much slower due to this.", e);
getCallerClass = null;
java7u25CompensationOffset = -1;
}
SUN_REFLECTION_SUPPORTED = getCallerClass != null;
GET_CALLER_CLASS = getCallerClass;
JDK_7u25_OFFSET = java7u25CompensationOffset;
protected static final Logger LOGGER = StatusLogger.getLogger();
private static PrivateSecurityManager SECURITY_MANAGER;
static {
PrivateSecurityManager psm;
try {
final SecurityManager sm = System.getSecurityManager();
......@@ -106,47 +67,48 @@ public final class ReflectionUtil {
SECURITY_MANAGER = psm;
}
private ReflectionUtil() {
protected DefaultStackLocator() {
}
public static boolean supportsFastReflection() {
return SUN_REFLECTION_SUPPORTED;
protected PrivateSecurityManager getSecurityManager() {
return SECURITY_MANAGER;
}
// TODO: return Object.class instead of null (though it will have a null ClassLoader)
// (MS) I believe this would work without any modifications elsewhere, but I could be wrong
// migrated from ReflectiveCallerClassUtility
@PerformanceSensitive
public static Class<?> getCallerClass(final int depth) {
public Class<?> getCallerClass(final int depth) {
if (depth < 0) {
throw new IndexOutOfBoundsException(Integer.toString(depth));
}
// note that we need to add 1 to the depth value to compensate for this method, but not for the Method.invoke
// since Reflection.getCallerClass ignores the call to Method.invoke()
if (supportsFastReflection()) {
try {
return (Class<?>) GET_CALLER_CLASS.invoke(null, depth + 1 + JDK_7u25_OFFSET);
} catch (final Exception e) {
// theoretically this could happen if the caller class were native code
LOGGER.error("Error in ReflectionUtil.getCallerClass({}).", depth, e);
// TODO: return Object.class
return null;
}
}
// TODO: SecurityManager-based version?
// slower fallback method using stack trace
final StackTraceElement element = getEquivalentStackTraceElement(depth + 1);
final StackTraceElement element = getStackTraceElement(depth + 1);
try {
return LoaderUtil.loadClass(element.getClassName());
} catch (final ClassNotFoundException e) {
LOGGER.error("Could not find class in ReflectionUtil.getCallerClass({}).", depth, e);
LOGGER.error("Could not find class in StackLocatorUtil.getCallerClass({}).", depth, e);
}
// TODO: return Object.class
return null;
}
static StackTraceElement getEquivalentStackTraceElement(final int depth) {
public StackTraceElement calcLocation(final String fqcnOfLogger) {
if (fqcnOfLogger == null) {
return null;
}
// LOG4J2-1029 new Throwable().getStackTrace is faster than Thread.currentThread().getStackTrace().
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
StackTraceElement last = null;
for (int i = stackTrace.length - 1; i > 0; i--) {
final String className = stackTrace[i].getClassName();
if (fqcnOfLogger.equals(className)) {
return last;
}
last = stackTrace[i];
}
return null;
}
public StackTraceElement getStackTraceElement(final int depth) {
// (MS) I tested the difference between using Throwable.getStackTrace() and Thread.getStackTrace(), and
// the version using Throwable was surprisingly faster! at least on Java 1.8. See ReflectionBenchmark.
final StackTraceElement[] elements = new Throwable().getStackTrace();
......@@ -163,7 +125,7 @@ public final class ReflectionUtil {
throw new IndexOutOfBoundsException(Integer.toString(depth));
}
private static boolean isValid(final StackTraceElement element) {
private boolean isValid(final StackTraceElement element) {
// ignore native methods (oftentimes are repeated frames)
if (element.isNativeMethod()) {
return false;
......@@ -199,28 +161,13 @@ public final class ReflectionUtil {
// migrated from ClassLoaderContextSelector
@PerformanceSensitive
public static Class<?> getCallerClass(final String fqcn) {
public Class<?> getCallerClass(final String fqcn) {
return getCallerClass(fqcn, Strings.EMPTY);
}
// migrated from Log4jLoggerFactory
@PerformanceSensitive
public static Class<?> getCallerClass(final String fqcn, final String pkg) {
if (supportsFastReflection()) {
boolean next = false;
Class<?> clazz;
for (int i = 2; null != (clazz = getCallerClass(i)); i++) {
if (fqcn.equals(clazz.getName())) {
next = true;
continue;
}
if (next && clazz.getName().startsWith(pkg)) {
return clazz;
}
}
// TODO: return Object.class
return null;
}
public Class<?> getCallerClass(final String fqcn, final String pkg) {
if (SECURITY_MANAGER != null) {
return SECURITY_MANAGER.getCallerClass(fqcn, pkg);
}
......@@ -235,21 +182,7 @@ public final class ReflectionUtil {
// added for use in LoggerAdapter implementations mainly
@PerformanceSensitive
public static Class<?> getCallerClass(final Class<?> anchor) {
if (supportsFastReflection()) {
boolean next = false;
Class<?> clazz;
for (int i = 2; null != (clazz = getCallerClass(i)); i++) {
if (anchor.equals(clazz)) {
next = true;
continue;
}
if (next) {
return clazz;
}
}
return Object.class;
}
public Class<?> getCallerClass(final Class<?> anchor) {
if (SECURITY_MANAGER != null) {
return SECURITY_MANAGER.getCallerClass(anchor);
}
......@@ -279,7 +212,7 @@ public final class ReflectionUtil {
// migrated from ThrowableProxy
@PerformanceSensitive
public static Stack<Class<?>> getCurrentStackTrace() {
public Stack<Class<?>> getCurrentStackTrace() {
// benchmarks show that using the SecurityManager is much faster than looping through getCallerClass(int)
if (SECURITY_MANAGER != null) {
final Class<?>[] array = SECURITY_MANAGER.getClassContext();
......@@ -290,15 +223,6 @@ public final class ReflectionUtil {
}
return classes;
}
// slower version using getCallerClass where we cannot use a SecurityManager
if (supportsFastReflection()) {
final Stack<Class<?>> classes = new Stack<>();
Class<?> clazz;
for (int i = 1; null != (clazz = getCallerClass(i)); i++) {
classes.push(clazz);
}
return classes;
}
return new Stack<>();
}
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.logging.log4j.util;
import java.lang.reflect.Method;
import java.util.Stack;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
/**
* <em>Consider this class private.</em> Provides various methods to determine the caller class. <h3>Background</h3>
* <p>
* This method, available only in the Oracle/Sun/OpenJDK implementations of the Java Virtual Machine, is a much more
* efficient mechanism for determining the {@link Class} of the caller of a particular method. When it is not available,
* a {@link SecurityManager} is the second-best option. When this is also not possible, the {@code StackTraceElement[]}
* returned by {@link Throwable#getStackTrace()} must be used, and its {@code String} class name converted to a
* {@code Class} using the slow {@link Class#forName} (which can add an extra microsecond or more for each invocation
* depending on the runtime ClassLoader hierarchy).
* </p>
* <p>
* During Java 8 development, the {@code sun.reflect.Reflection.getCallerClass(int)} was removed from OpenJDK, and this
* change was back-ported to Java 7 in version 1.7.0_25 which changed the behavior of the call and caused it to be off
* by one stack frame. This turned out to be beneficial for the survival of this API as the change broke hundreds of
* libraries and frameworks relying on the API which brought much more attention to the intended API removal.
* </p>
* <p>
* After much community backlash, the JDK team agreed to restore {@code getCallerClass(int)} and keep its existing
* behavior for the rest of Java 7. However, the method is deprecated in Java 8, and current Java 9 development has not
* addressed this API. Therefore, the functionality of this class cannot be relied upon for all future versions of Java.
* It does, however, work just fine in Sun JDK 1.6, OpenJDK 1.6, Oracle/OpenJDK 1.7, and Oracle/OpenJDK 1.8. Other Java
* environments may fall back to using {@link Throwable#getStackTrace()} which is significantly slower due to
* examination of every virtual frame of execution.
* </p>
*/
public final class ReflectionStackLocator extends DefaultStackLocator {
// Checkstyle Suppress: the lower-case 'u' ticks off CheckStyle...
// CHECKSTYLE:OFF
static final int JDK_7u25_OFFSET;
// CHECKSTYLE:OFF
private static final boolean SUN_REFLECTION_SUPPORTED;
private static final Method GET_CALLER_CLASS;
private static final ReflectionStackLocator INSTANCE;
static {
Method getCallerClass;
int java7u25CompensationOffset = 0;
try {
final Class<?> sunReflectionClass = LoaderUtil.loadClass("sun.reflect.Reflection");
getCallerClass = sunReflectionClass.getDeclaredMethod("getCallerClass", int.class);
Object o = getCallerClass.invoke(null, 0);
final Object test1 = getCallerClass.invoke(null, 0);
if (o == null || o != sunReflectionClass) {
LOGGER.warn("Unexpected return value from Reflection.getCallerClass(): {}", test1);
getCallerClass = null;
java7u25CompensationOffset = -1;
} else {
o = getCallerClass.invoke(null, 1);
if (o == sunReflectionClass) {
LOGGER.warn("You are using Java 1.7.0_25 which has a broken implementation of "
+ "Reflection.getCallerClass.");
LOGGER.warn("You should upgrade to at least Java 1.7.0_40 or later.");
LOGGER.debug("Using stack depth compensation offset of 1 due to Java 7u25.");
java7u25CompensationOffset = 1;
}
}
} catch (final Exception | LinkageError e) {
LOGGER.info("sun.reflect.Reflection.getCallerClass is not supported. "
+ "ReflectionUtil.getCallerClass will be much slower due to this.", e);
getCallerClass = null;
java7u25CompensationOffset = -1;
}
SUN_REFLECTION_SUPPORTED = getCallerClass != null;
GET_CALLER_CLASS = getCallerClass;
JDK_7u25_OFFSET = java7u25CompensationOffset;
INSTANCE = new ReflectionStackLocator();
}
public static StackLocator getInstance() {
return INSTANCE;
}
private ReflectionStackLocator() {
}
// TODO: return Object.class instead of null (though it will have a null ClassLoader)
// (MS) I believe this would work without any modifications elsewhere, but I could be wrong
// migrated from ReflectiveCallerClassUtility
@PerformanceSensitive
public Class<?> getCallerClass(final int depth) {
if (depth < 0) {
throw new IndexOutOfBoundsException(Integer.toString(depth));
}
// note that we need to add 1 to the depth value to compensate for this method, but not for the Method.invoke
// since Reflection.getCallerClass ignores the call to Method.invoke()
try {
return (Class<?>) GET_CALLER_CLASS.invoke(null, depth + 1 + JDK_7u25_OFFSET);
} catch (final Exception e) {
// theoretically this could happen if the caller class were native code
LOGGER.error("Error in ReflectionUtil.getCallerClass({}).", depth, e);
// TODO: return Object.class
return null;
}
}
// migrated from Log4jLoggerFactory
@PerformanceSensitive
public Class<?> getCallerClass(final String fqcn, final String pkg) {
boolean next = false;
Class<?> clazz;
for (int i = 2; null != (clazz = getCallerClass(i)); i++) {
if (fqcn.equals(clazz.getName())) {
next = true;
continue;
}
if (next && clazz.getName().startsWith(pkg)) {
return clazz;
}
}
// TODO: return Object.class
return null;
}
// added for use in LoggerAdapter implementations mainly
@PerformanceSensitive
public Class<?> getCallerClass(final Class<?> anchor) {
boolean next = false;
Class<?> clazz;
for (int i = 2; null != (clazz = getCallerClass(i)); i++) {
if (anchor.equals(clazz)) {
next = true;
continue;
}
if (next) {
return clazz;
}
}
return Object.class;
}
// migrated from ThrowableProxy
@PerformanceSensitive
public Stack<Class<?>> getCurrentStackTrace() {
// benchmarks show that using the SecurityManager is much faster than looping through getCallerClass(int)
if (getSecurityManager() != null) {
final Class<?>[] array = getSecurityManager().getClassContext();
final Stack<Class<?>> classes = new Stack<>();
classes.ensureCapacity(array.length);
for (final Class<?> clazz : array) {
classes.push(clazz);
}
return classes;
}
// slower version using getCallerClass where we cannot use a SecurityManager
final Stack<Class<?>> classes = new Stack<>();
Class<?> clazz;
for (int i = 1; null != (clazz = getCallerClass(i)); i++) {
classes.push(clazz);
}
return classes;
}
}
......@@ -16,20 +16,24 @@
*/
package org.apache.logging.log4j.util;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Stack;
/**
* Test walking the stack using StackWalker.
* Interface for methods used to locate information about the caller.
*/
public class ReflectionUtilTest {
@Test
public void testLocateClass() {
ClassLocator locator = new ClassLocator();
Class<?> clazz = locator.locateClass();
assertNotNull("Could not locate class", clazz);
assertEquals("Incorrect class", this.getClass(), clazz);
}
public interface StackLocator {
Class<?> getCallerClass(final int depth);
StackTraceElement getStackTraceElement(final int depth);
Class<?> getCallerClass(final String fqcn);
Class<?> getCallerClass(final String fqcn, final String pkg);
Class<?> getCallerClass(final Class<?> anchor);
Stack<Class<?>> getCurrentStackTrace();
StackTraceElement calcLocation(final String fqcnOfLogger);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.logging.log4j.util;
import java.util.Stack;
/**
* <em>Consider this class private.</em> Provides various methods to determine the caller class. <h3>Background</h3>
*/
public final class StackLocatorUtil {
private static StackLocator stackLocator = null;
static {
try {
final Class<?> stackLocatorClass = LoaderUtil.loadClass("org.apache.logging.log4j.util.StackWalkerStackLocator");
stackLocator = (StackLocator) stackLocatorClass.newInstance();
} catch (ClassNotFoundException cnfe) {
// Ignore this exception.
} catch (InstantiationException ie) {
// Ignore this exception.
} catch (IllegalAccessException iae) {
// Ignore this exception.
} catch (UnsupportedClassVersionError error) {
// Ignore this error.
}
if (stackLocator == null) {
try {
final Class<?> stackLocatorClass = LoaderUtil.loadClass("sun.reflect.Reflection");
stackLocator = ReflectionStackLocator.getInstance();
} catch (ClassNotFoundException cnfe) {
// Ignore this exception.
}
}
if (stackLocator == null) {
stackLocator = new DefaultStackLocator();
}
}
private StackLocatorUtil() {
}
// TODO: return Object.class instead of null (though it will have a null ClassLoader)
// (MS) I believe this would work without any modifications elsewhere, but I could be wrong
// migrated from ReflectiveCallerClassUtility
@PerformanceSensitive
public static Class<?> getCallerClass(final int depth) {
return stackLocator.getCallerClass(depth + 1);
}
public static StackTraceElement getStackTraceElement(final int depth) {
return stackLocator.getStackTraceElement(depth + 1);
}
// migrated from ClassLoaderContextSelector
@PerformanceSensitive
public static Class<?> getCallerClass(final String fqcn) {
return getCallerClass(fqcn, Strings.EMPTY);
}
// migrated from Log4jLoggerFactory
@PerformanceSensitive
public static Class<?> getCallerClass(final String fqcn, final String pkg) {
return stackLocator.getCallerClass(fqcn, pkg);
}
// added for use in LoggerAdapter implementations mainly
@PerformanceSensitive
public static Class<?> getCallerClass(final Class<?> anchor) {
return stackLocator.getCallerClass(anchor);
}
// migrated from ThrowableProxy
@PerformanceSensitive
public static Stack<Class<?>> getCurrentStackTrace() {
return stackLocator.getCurrentStackTrace();
}
public static StackTraceElement calcLocation(final String fqcnOfLogger) {
return stackLocator.calcLocation(fqcnOfLogger);
}
}
......@@ -23,31 +23,41 @@ import java.util.stream.Collectors;
/**
* <em>Consider this class private.</em> Determines the caller's class.
*/
public class ReflectionUtil {
public class StackWalkerStackLocator implements StackLocator {
private final static StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
public static Class<?> getCallerClass(final String fqcn) {
private final static StackWalker stackWalker = StackWalker.getInstance();
public Class<?> getCallerClass(final String fqcn) {
return getCallerClass(fqcn, "");
}
public static Class<?> getCallerClass(final String fqcn, final String pkg) {
public Class<?> getCallerClass(final String fqcn, final String pkg) {
return walker.walk(s -> s.filter(new ClassNamePredicate(fqcn)).findFirst()).get().getDeclaringClass();
}
public static Class<?> getCallerClass(final Class<?> anchor) {
public Class<?> getCallerClass(final Class<?> anchor) {
return walker.walk(s -> s.filter(new ClassPredicate(anchor)).findFirst()).get().getDeclaringClass();
}
public static Class<?> getCallerClass(final int depth) {
return walker.walk(s -> s.skip(depth - 1)).findFirst().get().getDeclaringClass();
public Class<?> getCallerClass(final int depth) {
;
return walker.walk(s -> s.skip(depth).findFirst()).get().getDeclaringClass();
}
public static Stack<Class<?>> getCurrentStackTrace() {
public Stack<Class<?>> getCurrentStackTrace() {
Stack<Class<?>> stack = new Stack<Class<?>>();
List<Class<?>> classes = walker.walk(s -> s.map(f -> f.getDeclaringClass()).collect(Collectors.toList()));
stack.addAll(classes);
return stack;
}
public StackTraceElement calcLocation(final String fqcnOfLogger) {
return stackWalker.walk(s -> s.filter(new ClassNamePredicate(fqcnOfLogger)).findFirst()).get().toStackTraceElement();
}
public StackTraceElement getStackTraceElement(final int depth) {
return stackWalker.walk(s -> s.skip(depth).findFirst()).get().toStackTraceElement();
}
}
......@@ -18,6 +18,7 @@
package org.apache.logging.log4j.message;
import org.apache.logging.log4j.junit.Mutable;
import org.apache.logging.log4j.util.Constants;
import org.junit.Test;
import static org.junit.Assert.*;
......@@ -29,6 +30,8 @@ import java.util.Locale;
*/
public class MessageFormatMessageTest {
private static final String SPACE = Constants.JAVA_MAJOR_VERSION < 9 ? " " : "\u00a0";
private static final int LOOP_CNT = 500;
String[] array = new String[LOOP_CNT];
......@@ -69,7 +72,7 @@ public class MessageFormatMessageTest {
final String testMsg = "Test message {0,number,currency}";
final MessageFormatMessage msg = new MessageFormatMessage(Locale.FRANCE, testMsg, 1234567890);
final String result = msg.getFormattedMessage();
final String expected = "Test message 1 234 567 890,00 €";
final String expected = "Test message 1 234 567 890,00" + SPACE + "€";
assertEquals(expected, result);
}
......
......@@ -22,6 +22,6 @@ package org.apache.logging.log4j.util;
public class ClassLocator {
public Class<?> locateClass() {
return ReflectionUtil.getCallerClass(ClassLocator.class);
return StackLocatorUtil.getCallerClass(ClassLocator.class);
}
}
......@@ -16,14 +16,12 @@
*/
package org.apache.logging.log4j.util;
import org.apache.logging.log4j.core.impl.LocationLocator;
/**
*
*/
public class ClassNameLocator {
public StackTraceElement locateClass() {
return LocationLocator.calcLocation(ClassNameLocator.class.getName());
return StackLocatorUtil.calcLocation(ClassNameLocator.class.getName());
}
}
......@@ -29,31 +29,16 @@ import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;
@RunWith(BlockJUnit4ClassRunner.class)
public class ReflectionUtilTest {
public class StackLocatorUtilTest {
@Before
public void setUp() throws Exception {
assumeTrue(ReflectionUtil.supportsFastReflection());
}
@Test
public void testSunReflectionEquivalence() throws Exception {
// can't start at 0 because Reflection != ReflectionUtil
for (int i = 1; i < 6; i++) {
assertSame(
Reflection.getCallerClass(i + ReflectionUtil.JDK_7u25_OFFSET),
ReflectionUtil.getCallerClass(i)
);
}
}
@Test
public void testStackTraceEquivalence() throws Exception {
for (int i = 1; i < 15; i++) {
final Class<?> expected = Reflection.getCallerClass(i + ReflectionUtil.JDK_7u25_OFFSET);
final Class<?> actual = ReflectionUtil.getCallerClass(i);
final Class<?> expected = Reflection.getCallerClass(i + ReflectionStackLocator.JDK_7u25_OFFSET);
final Class<?> actual = StackLocatorUtil.getCallerClass(i);
final Class<?> fallbackActual = Class.forName(
ReflectionUtil.getEquivalentStackTraceElement(i).getClassName());
StackLocatorUtil.getStackTraceElement(i).getClassName());
assertSame(expected, actual);
assertSame(expected, fallbackActual);
}
......@@ -61,37 +46,37 @@ public class ReflectionUtilTest {
@Test
public void testGetCallerClass() throws Exception {
final Class<?> expected = ReflectionUtilTest.class;
final Class<?> actual = ReflectionUtil.getCallerClass(1);
final Class<?> expected = StackLocatorUtilTest.class;
final Class<?> actual = StackLocatorUtil.getCallerClass(1);
assertSame(expected, actual);
}
@Test
public void testGetCallerClassNameViaStackTrace() throws Exception {
final Class<?> expected = ReflectionUtilTest.class;
final Class<?> expected = StackLocatorUtilTest.class;
final Class<?> actual = Class.forName(new Throwable().getStackTrace()[0].getClassName());
assertSame(expected, actual);
}
@Test
public void testGetCurrentStackTrace() throws Exception {
final Stack<Class<?>> classes = ReflectionUtil.getCurrentStackTrace();
final Stack<Class<?>> classes = StackLocatorUtil.getCurrentStackTrace();
final Stack<Class<?>> reversed = new Stack<>();
reversed.ensureCapacity(classes.size());
while (!classes.empty()) {
reversed.push(classes.pop());
}
while (reversed.peek() != ReflectionUtil.class) {
while (reversed.peek() != StackLocatorUtil.class) {
reversed.pop();
}
reversed.pop(); // ReflectionUtil
assertSame(ReflectionUtilTest.class, reversed.pop());
assertSame(StackLocatorUtilTest.class, reversed.pop());
}
@Test
public void testGetCallerClassViaName() throws Exception {
final Class<?> expected = BlockJUnit4ClassRunner.class;
final Class<?> actual = ReflectionUtil.getCallerClass("org.junit.runners.ParentRunner");
final Class<?> actual = StackLocatorUtil.getCallerClass("org.junit.runners.ParentRunner");
// if this test fails in the future, it's probably because of a JUnit upgrade; check the new stack trace and
// update this test accordingly
assertSame(expected, actual);
......@@ -100,9 +85,18 @@ public class ReflectionUtilTest {
@Test
public void testGetCallerClassViaAnchorClass() throws Exception {
final Class<?> expected = BlockJUnit4ClassRunner.class;
final Class<?> actual = ReflectionUtil.getCallerClass(ParentRunner.class);
final Class<?> actual = StackLocatorUtil.getCallerClass(ParentRunner.class);
// if this test fails in the future, it's probably because of a JUnit upgrade; check the new stack trace and
// update this test accordingly
assertSame(expected, actual);
}
@Test
public void testLocateClass() {
ClassLocator locator = new ClassLocator();
Class<?> clazz = locator.locateClass();
assertNotNull("Could not locate class", clazz);
assertEquals("Incorrect class", this.getClass(), clazz);
}
}
......@@ -38,12 +38,6 @@
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<!-- The Java 9 jar is used to pull in the Java 9 specific classes -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-java9</artifactId>
<scope>provided</scope>
</dependency>
<!-- Used for OSGi bundle support -->
<dependency>
<groupId>org.osgi</groupId>
......@@ -351,11 +345,10 @@
<execution>
<!-- disable annotation processing for first pass -->
<id>default-compile</id>
<goals>
<goal>compile</goal>
</goals>
<phase>compile</phase>
<configuration>
<excludes>
<exclude>module-info.java</exclude>
</excludes>
<proc>none</proc>
</configuration>
</execution>
......@@ -367,6 +360,9 @@
</goals>
<phase>process-classes</phase>
<configuration>
<excludes>
<exclude>module-info.java</exclude>
</excludes>
<proc>only</proc>
</configuration>
</execution>
......@@ -408,7 +404,6 @@
<Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
<X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
<X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</archive>
</configuration>
......@@ -436,26 +431,6 @@
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-java9-supplement</id>
<phase>process-classes</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>org.apache.logging.log4j</includeGroupIds>
<includeArtifactIds>log4j-java9</includeArtifactIds>
<excludeTransitive>false</excludeTransitive>
<includes>org/apache/logging/log4j/core/**/*.class</includes>
<outputDirectory>${project.build.directory}/classes/META-INF/versions/9</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
......
......@@ -27,7 +27,6 @@ import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.ReliabilityStrategy;
import org.apache.logging.log4j.core.impl.LocationLocator;
import org.apache.logging.log4j.core.impl.ContextDataFactory;
import org.apache.logging.log4j.core.ContextDataInjector;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
......@@ -39,6 +38,7 @@ import org.apache.logging.log4j.message.AsynchronouslyFormattable;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.message.ReusableMessage;
import org.apache.logging.log4j.util.StackLocatorUtil;
import org.apache.logging.log4j.util.StringMap;
import org.apache.logging.log4j.status.StatusLogger;
......@@ -219,7 +219,7 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
// location: very expensive operation. LOG4J2-153:
// Only include if "includeLocation=true" is specified,
// exclude if not specified or if "false" was specified.
return includeLocation ? LocationLocator.calcLocation(fqcn) : null;
return includeLocation ? StackLocatorUtil.calcLocation(fqcn) : null;
}
/**
......
package org.apache.logging.log4j.core.config.plugins.convert;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
/**
*
*/
public class Base64Converter {
private static final Logger LOGGER = StatusLogger.getLogger();
private static Method method = null;
private static Object decoder = null;
static {
try {
// Base64 is available in Java 8 and up.
Class<?> clazz = LoaderUtil.loadClass("java.util.Base64");
Method getDecoder = clazz.getMethod("getDecoder", null);
decoder = getDecoder.invoke(null, null);
clazz = decoder.getClass();
method = clazz.getMethod("decode", String.class);
} catch (ClassNotFoundException ex) {
} catch (NoSuchMethodException ex) {
} catch (IllegalAccessException ex) {
} catch (InvocationTargetException ex) {
}
if (method == null) {
try {
// DatatypeConverter is not in the default module in Java 9.
final Class<?> clazz = LoaderUtil.loadClass("javax.xml.bind.DatatypeConverter");
method = clazz.getMethod("parseBase64Binary", String.class);
} catch (ClassNotFoundException ex) {
LOGGER.error("No Base64 Converter is available");
} catch (NoSuchMethodException ex) {
}
}
}
public static byte[] parseBase64Binary(String encoded) {
if (method == null) {
LOGGER.error("No base64 converter");
} else {
try {
return (byte[]) method.invoke(decoder, encoded);
} catch (IllegalAccessException ex) {
LOGGER.error("Error decoding string - " + ex.getMessage());
} catch (InvocationTargetException ex) {
LOGGER.error("Error decoding string - " + ex.getMessage());
}
}
return new byte[0];
}
}
package org.apache.logging.log4j.core.config.plugins.convert;
/**
* Converts Strings to hex. This is used in place of java.xml.bind.DataTypeConverter which is not available by
* default in Java 9.
*/
public class HexConverter {
public static byte[] parseHexBinary(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}
......@@ -32,7 +32,6 @@ import java.security.Provider;
import java.security.Security;
import java.util.UUID;
import java.util.regex.Pattern;
import javax.xml.bind.DatatypeConverter;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
......@@ -113,10 +112,10 @@ public final class TypeConverters {
bytes = new byte[0];
} else if (value.startsWith(PREFIX_BASE64)) {
final String lexicalXSDBase64Binary = value.substring(PREFIX_BASE64.length());
bytes = DatatypeConverter.parseBase64Binary(lexicalXSDBase64Binary);
bytes = Base64Converter.parseBase64Binary(lexicalXSDBase64Binary);
} else if (value.startsWith(PREFIX_0x)) {
final String lexicalXSDHexBinary = value.substring(PREFIX_0x.length());
bytes = DatatypeConverter.parseHexBinary(lexicalXSDHexBinary);
bytes = HexConverter.parseHexBinary(lexicalXSDHexBinary);
} else {
bytes = value.getBytes(Charset.defaultCharset());
}
......
......@@ -67,17 +67,25 @@ public class PluginProcessor extends AbstractProcessor {
@Override
public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
System.out.println("Processing annotations");
try {
final Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Plugin.class);
if (elements.isEmpty()) {
System.out.println("No elements to process");
return false;
}
collectPlugins(elements);
writeCacheFile(elements.toArray(new Element[elements.size()]));
System.out.println("Annotations processed");
return true;
} catch (final IOException e) {
e.printStackTrace();
error(e.getMessage());
return false;
} catch (final Exception ex) {
ex.printStackTrace();
error(ex.getMessage());
return false;
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment