< prev index next >
jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java
Print this page
@@ -28,13 +28,13 @@
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.io.*;
import java.time.Clock;
-
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.function.Predicate;
/**
* LogRecord objects are used to pass logging requests between
* the logging framework and individual log Handlers.
* <p>
@@ -637,45 +637,64 @@
}
// Private method to infer the caller's class and method names
private void inferCaller() {
needToInferCaller = false;
- JavaLangAccess access = SharedSecrets.getJavaLangAccess();
- Throwable throwable = new Throwable();
- int depth = access.getStackTraceDepth(throwable);
-
- boolean lookingForLogger = true;
- for (int ix = 0; ix < depth; ix++) {
- // Calling getStackTraceElement directly prevents the VM
- // from paying the cost of building the entire stack frame.
- StackTraceElement frame =
- access.getStackTraceElement(throwable, ix);
- String cname = frame.getClassName();
- boolean isLoggerImpl = isLoggerImplFrame(cname);
- if (lookingForLogger) {
// Skip all frames until we have found the first logger frame.
- if (isLoggerImpl) {
- lookingForLogger = false;
- }
- } else {
- if (!isLoggerImpl) {
- // skip reflection call
- if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
- // We've found the relevant frame.
- setSourceClassName(cname);
- setSourceMethodName(frame.getMethodName());
- return;
- }
- }
- }
- }
+ Optional<StackWalker.StackFrame> frame = new CallerFinder().get();
+ frame.ifPresent(f -> {
+ setSourceClassName(f.getClassName());
+ setSourceMethodName(f.getMethodName());
+ });
+
// We haven't found a suitable frame, so just punt. This is
// OK as we are only committed to making a "best effort" here.
}
- private boolean isLoggerImplFrame(String cname) {
- // the log record could be created for a platform logger
- return (cname.equals("java.util.logging.Logger") ||
- cname.startsWith("java.util.logging.LoggingProxyImpl") ||
- cname.startsWith("sun.util.logging."));
+ /*
+ * CallerFinder is a stateful predicate.
+ */
+ static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
+ static final StackWalker WALKER = StackWalker.create();
+
+ /**
+ * Returns StackTraceElement of the caller's frame.
+ * @return StackTraceElement of the caller's frame.
+ */
+ Optional<StackWalker.StackFrame> get() {
+ return WALKER.walk((s) -> s.filter(this).findFirst());
+ }
+
+ private boolean lookingForLogger = true;
+ /**
+ * Returns true if we have found the caller's frame, false if the frame
+ * must be skipped.
+ *
+ * @param t The frame info.
+ * @return true if we have found the caller's frame, false if the frame
+ * must be skipped.
+ */
+ @Override
+ public boolean test(StackWalker.StackFrame t) {
+ final String cname = t.getClassName();
+ // We should skip all frames until we have found the logger,
+ // because these frames could be frames introduced by e.g. custom
+ // sub classes of Handler.
+ if (lookingForLogger) {
+ lookingForLogger = !cname.equals("java.util.logging.Logger") &&
+ !cname.startsWith("java.util.logging.LoggingProxyImpl") &&
+ !cname.startsWith("sun.util.logging.");
+ return false;
+ }
+ // Once the logger is found - we should skip all frames that
+ // point to packages which contain artifacts that could be
+ // inserted between the logger and its caller. These could be
+ // logger wrappers from j.u.l or sun.uti.logging (e.g. the
+ // PlatformLogger or artifacts between the PlatformLogger and
+ // the actual logger) or frames inserted by use of reflection
+ // and/or doPrivileged calls.
+ return !cname.startsWith("java.util.logging.")
+ && !cname.startsWith("sun.util.logging.")
+ && !cname.startsWith("java.security.AccessController");
+ }
}
}
< prev index next >