private static Class<?> callerClass(final Class<?> clazz) { if (clazz != null) { return clazz; } final Class<?> candidate = StackLocatorUtil.getCallerClass(3); if (candidate == null) { throw new UnsupportedOperationException("No class provided, and an appropriate one cannot be found."); } return candidate; }
public StackTraceElement locateClass() { return StackLocatorUtil.calcLocation(ClassNameLocator.class.getName()); } }
@Test public void testStackTraceEquivalence() throws Exception { for (int i = 1; i < 15; i++) { final Class<?> expected = Reflection.getCallerClass(i + StackLocator.JDK_7u25_OFFSET); final Class<?> actual = StackLocatorUtil.getCallerClass(i); final Class<?> fallbackActual = Class.forName( StackLocatorUtil.getStackTraceElement(i).getClassName()); assertSame(expected, actual); assertSame(expected, fallbackActual); } }
@Test public void testGetCurrentStackTrace() throws Exception { 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() != StackLocatorUtil.class) { reversed.pop(); } reversed.pop(); // ReflectionUtil assertSame(StackLocatorUtilTest.class, reversed.pop()); }
/** * Constructs the wrapper for the Throwable that includes packaging data. * * @param throwable The Throwable to wrap, must not be null. * @param visited The set of visited suppressed exceptions. */ private ThrowableProxy(final Throwable throwable, final Set<Throwable> visited) { this.throwable = throwable; this.name = throwable.getClass().getName(); this.message = throwable.getMessage(); this.localizedMessage = throwable.getLocalizedMessage(); Stack<Class<?>> stack; try { Class<?>[] classCtx = (Class<?>[]) classContextMethod.invoke(throwable); stack = new Stack<Class<?>>(); stack.addAll(Arrays.asList(classCtx)); } catch (Exception e) { stack = StackLocatorUtil.getCurrentStackTrace(); } final Map<String, CacheEntry> map = new HashMap<>(); this.extendedStackTrace = this.toExtendedStackTrace(stack, map, null, throwable.getStackTrace()); final Throwable throwableCause = throwable.getCause(); final Set<Throwable> causeVisited = new HashSet<>(1); this.causeProxy = throwableCause == null ? null : new ThrowableProxy(throwable, stack, map, throwableCause, visited, causeVisited); this.suppressedProxies = this.toSuppressedProxies(throwable, visited); }
/** * Returns a Logger with the name of the calling class. * * @param messageFactory The message factory is used only when creating a logger, subsequent use does not change the * logger but will log a warning if mismatched. * @return The Logger for the calling class. * @throws UnsupportedOperationException if the calling class cannot be determined. */ public static Logger getLogger(final MessageFactory messageFactory) { return getLogger(StackLocatorUtil.getCallerClass(2), messageFactory); }
/** * Returns the caller location if requested, {@code null} otherwise. * * @param fqcn fully qualified caller name. * @return the caller location if requested, {@code null} otherwise. */ private StackTraceElement calcLocationIfRequested(final String fqcn) { // location: very expensive operation. LOG4J2-153: // Only include if "includeLocation=true" is specified, // exclude if not specified or if "false" was specified. return includeLocation ? StackLocatorUtil.calcLocation(fqcn) : null; }
/** * Returns a Logger with the name of the calling class. * * @return The Logger for the calling class. * @throws UnsupportedOperationException if the calling class cannot be determined. */ public static Logger getLogger() { return getLogger(StackLocatorUtil.getCallerClass(2)); }
/** * Returns the StackTraceElement for the caller. This will be the entry that occurs right * before the first occurrence of FQCN as a class name. * @return the StackTraceElement for the caller. */ @Override public StackTraceElement getSource() { if (source != null) { return source; } if (loggerFqcn == null || !includeLocation) { return null; } source = StackLocatorUtil.calcLocation(loggerFqcn); return source; }
/** * Returns a Logger using the fully qualified class name of the value as the Logger name. * * @param value The value whose class name should be used as the Logger name. If null the name of the calling class * will be used as the logger name. * @return The Logger. * @throws UnsupportedOperationException if {@code value} is {@code null} and the calling class cannot be * determined. */ public static Logger getLogger(final Object value) { return getLogger(value != null ? value.getClass() : StackLocatorUtil.getCallerClass(2)); }
/** * Returns the StackTraceElement for the caller. This will be the entry that occurs right * before the first occurrence of FQCN as a class name. * @return the StackTraceElement for the caller. */ @Override public StackTraceElement getSource() { if (source != null) { return source; } if (loggerFqcn == null || !includeLocation) { return null; } source = StackLocatorUtil.calcLocation(loggerFqcn); return source; }
/** * Returns a Logger using the fully qualified class name of the value as the Logger name. * * @param value The value whose class name should be used as the Logger name. If null the name of the calling class * will be used as the logger name. * @param messageFactory The message factory is used only when creating a logger, subsequent use does not change the * logger but will log a warning if mismatched. * @return The Logger. * @throws UnsupportedOperationException if {@code value} is {@code null} and the calling class cannot be * determined. */ public static Logger getLogger(final Object value, final MessageFactory messageFactory) { return getLogger(value != null ? value.getClass() : StackLocatorUtil.getCallerClass(2), messageFactory); }
return getLogger(clazz != null ? clazz : StackLocatorUtil.getCallerClass(2), StringFormatterMessageFactory.INSTANCE);
public Class<?> locateClass() { return StackLocatorUtil.getCallerClass(ClassLocator.class); } }
/** * Returns a formatter Logger using the fully qualified name of the calling Class as the Logger name. * <p> * This logger lets you use a {@link java.util.Formatter} string in the message to format parameters. * </p> * * @return The Logger for the calling class. * @throws UnsupportedOperationException if the calling class cannot be determined. * @since 2.4 */ public static Logger getFormatterLogger() { return getFormatterLogger(StackLocatorUtil.getCallerClass(2)); }
@PerformanceSensitive public static Class<?> getCallerClass(final String fqcn) { return getCallerClass(fqcn, Strings.EMPTY); }
@Override protected LoggerContext getContext() { final Class<?> anchor = StackLocatorUtil.getCallerClass(FQCN, PACKAGE); return anchor == null ? LogManager.getContext() : getContext(StackLocatorUtil.getCallerClass(anchor)); }
return getLogger(value != null ? value.getClass() : StackLocatorUtil.getCallerClass(2), StringFormatterMessageFactory.INSTANCE);
/** * Returns a Logger with the specified name. * * @param name The logger name. If null the name of the calling class will be used. * @return The Logger. * @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(StackLocatorUtil.getCallerClass(2)); }
/** * Returns a Logger with the specified name. * * @param name The logger name. If null the name of the calling class will be used. * @param messageFactory The message factory is used only when creating a logger, subsequent use does not change the * logger but will log a warning if mismatched. * @return The Logger. * @throws UnsupportedOperationException if {@code name} is {@code null} and the calling class cannot be determined. */ public static Logger getLogger(final String name, final MessageFactory messageFactory) { return name != null ? getContext(false).getLogger(name, messageFactory) : getLogger( StackLocatorUtil.getCallerClass(2), messageFactory); }