Top Description Fields Constructors Methods
org.apache.logging.log4j.util

public final Class StackLocator

extends Object
Class Inheritance
Annotations
@InternalApi
Imports
java.lang.reflect.Method, java.util.ArrayDeque, .Deque, java.util.function.Predicate

Consider this class private. Provides various methods to determine the caller class.

Background

This method, available only in the Oracle/Sun/OpenJDK implementations of the Java Virtual Machine, is a much more efficient mechanism for determining the Class of the caller of a particular method. When it is not available, a SecurityManager is the second-best option. When this is also not possible, the StackTraceElement[] returned by Throwable#getStackTrace() must be used, and its String class name converted to a Class using the slow Class#forName (which can add an extra microsecond or more for each invocation depending on the runtime ClassLoader hierarchy).

During Java 8 development, the 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.

After much community backlash, the JDK team agreed to restore 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 Throwable#getStackTrace() which is significantly slower due to examination of every virtual frame of execution.

Field Summary

Modifier and TypeField and Description
private static final Class<?>
DEFAULT_CALLER_CLASS

Todo

Use Object.class.

private static final Method
private static final StackLocator
pack-priv static final int
JDK_7U25_OFFSET

TODO Consider removing now that we require Java 8.

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
public StackTraceElement
calcLocation(final String fqcnOfLogger)

public Class<?>
getCallerClass(final Class<?> sentinelClass, final Predicate<Class<?>> callerPredicate)

public Class<?>

Returns:

A class or null.
getCallerClass
(final int
The stack frame count to walk.
depth
)

Gets the Class of the method that called this method at the location up the call stack by the given stack frame depth.

public Class<?>
getCallerClass(final String fqcn, final String pkg)

public Class<?>
getCallerClass(final Class<?> anchor)

public Deque<Class<?>>
public static StackLocator

Returns:

the singleton instance.
getInstance
()

Gets the singleton instance.

public StackTraceElement
getStackTraceElement(final int depth)

private boolean
isValid(final StackTraceElement element)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

DEFAULT_CALLER_CLASSback to summary
private static final Class<?> DEFAULT_CALLER_CLASS

Todo

Use Object.class.

GET_CALLER_CLASS_METHODback to summary
private static final Method GET_CALLER_CLASS_METHOD
INSTANCEback to summary
private static final StackLocator INSTANCE
JDK_7U25_OFFSETback to summary
pack-priv static final int JDK_7U25_OFFSET

TODO Consider removing now that we require Java 8.

Constructor Detail

StackLocatorback to summary
private StackLocator()

Method Detail

calcLocationback to summary
public StackTraceElement calcLocation(final String fqcnOfLogger)
getCallerClassback to summary
public Class<?> getCallerClass(final Class<?> sentinelClass, final Predicate<Class<?>> callerPredicate)
Annotations
@PerformanceSensitive
getCallerClassback to summary
public Class<?> getCallerClass(final int depth)

Gets the Class of the method that called this method at the location up the call stack by the given stack frame depth.

This method returns null if:

  • sun.reflect.Reflection.getCallerClass(int) is not present.
  • An exception is caught calling sun.reflect.Reflection.getCallerClass(int).
Parameters
depth:int

The stack frame count to walk.

Returns:Class<?>

A class or null.

Annotations
@PerformanceSensitive
Exceptions
IndexOutOfBoundsException:
if depth is negative.
getCallerClassback to summary
public Class<?> getCallerClass(final String fqcn, final String pkg)
Annotations
@PerformanceSensitive
getCallerClassback to summary
public Class<?> getCallerClass(final Class<?> anchor)
Annotations
@PerformanceSensitive
getCurrentStackTraceback to summary
public Deque<Class<?>> getCurrentStackTrace()
Annotations
@PerformanceSensitive
getInstanceback to summary
public static StackLocator getInstance()

Gets the singleton instance.

Returns:StackLocator

the singleton instance.

getStackTraceElementback to summary
public StackTraceElement getStackTraceElement(final int depth)
isValidback to summary
private boolean isValid(final StackTraceElement element)