/* * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
// Note: line numbers and lambda hashes will be erased when // comparing stack traces. However, the stack may change // if some methods are being renamed in the code base. // If the JDKcode base changes and the test fails because of that, // then after validating that the actual stack trace obtained // is indeed correct (no frames are skipped that shouldn't) // then you can cut & paste the <-- actual --> stack printed in the // test output in here: privatefinal String expected = "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:209)\n" + "2: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:145)\n" + "3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:158)\n" + "4: VerifyStackTrace.invoke(VerifyStackTrace.java:188)\n" + "5: VerifyStackTrace$1.run(VerifyStackTrace.java:218)\n" + "6: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" + "7: VerifyStackTrace.test(VerifyStackTrace.java:227)\n" + "8: VerifyStackTrace.main(VerifyStackTrace.java:182)\n";
// Note: line numbers and lambda hashes will be erased when // comparing stack traces. However, the stack may change // if some methods are being renamed in the code base. // If the JDK code base changes and the test fails because of that, // then after validating that the actual stack trace obtained // is indeed correct (no frames are skipped that shouldn't) // then you can cut & paste the <-- actual --> stack printed in the // test output in here (don't forget the final \n): privatefinal String expected = "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:211)\n" + "2: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:147)\n" + "3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:160)\n" + "4: VerifyStackTrace.invoke(VerifyStackTrace.java:190)\n" + "5: java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:94)\n" + "6: java.base/java.lang.reflect.Method.invoke(Method.java:520)\n" + "7: VerifyStackTrace$1.run(VerifyStackTrace.java:220)\n" + "8: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" + "9: VerifyStackTrace.test(VerifyStackTrace.java:229)\n" + "10: VerifyStackTrace.main(VerifyStackTrace.java:185)\n";
@Override public StackWalker walker() { return walker;}
@Override public String description() { return description;}
@Override public String expected() { return expected;}
} staticclass TestCase3 implements TestCase { privatefinal StackWalker walker = StackWalker.getInstance(
EnumSet.of(RETAIN_CLASS_REFERENCE, SHOW_HIDDEN_FRAMES));
// Note: line numbers and lambda hashes will be erased when // comparing stack traces. However, the stack may change // if some methods are being renamed in the code base. // If the JDK code base changes and the test fails because of that, // then after validating that the actual stack trace obtained // is indeed correct (no frames are skipped that shouldn't) // then you can cut & paste the <-- actual --> stack printed in the // test output in here (don't forget the final \n): privatefinal String expected = "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:280)\n" + "2: VerifyStackTrace$$Lambda$1/0x0000000801001848.run(Unknown Source)\n" + "3: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:206)\n" + "4: java.base/java.lang.invoke.DirectMethodHandle$Holder.invokeVirtual(DirectMethodHandle$Holder)\n" + "5: java.base/java.lang.invoke.LambdaForm$MH/0x0000000801004800.invoke_MT(LambdaForm$MH)\n" + "6: VerifyStackTrace$Handle.run(VerifyStackTrace.java:219)\n" + "7: VerifyStackTrace.invoke(VerifyStackTrace.java:259)\n" + "8: java.base/java.lang.invoke.LambdaForm$DMH/0x0000000801002000.invokeStatic(LambdaForm$DMH)\n" + "9: java.base/java.lang.invoke.LambdaForm$MH/0x0000000801003000.invoke(LambdaForm$MH)\n" + "10: java.base/java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder)\n" + "11: java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(DirectMethodHandleAccessor.java:211)\n" + "12: java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:122)\n" + "13: java.base/java.lang.reflect.Method.invoke(Method.java:573)\n" + "14: VerifyStackTrace$1.run(VerifyStackTrace.java:292)\n" + "15: java.base/java.security.AccessController.executePrivileged(AccessController.java:753)\n" + "16: java.base/java.security.AccessController.doPrivileged(AccessController.java:312)\n" + "17: VerifyStackTrace.test(VerifyStackTrace.java:301)\n" + "18: VerifyStackTrace.main(VerifyStackTrace.java:254)\n";
@Override public StackWalker walker() { return walker;}
@Override public String description() { return description;}
@Override public String expected() { return expected;}
}
static String prepare(String produced, boolean eraseSensitiveInfo) { if (eraseSensitiveInfo) { // Erase sensitive information before comparing: // comparing line numbers is too fragile, so we just erase them // out before comparing. We also erase the hash-like names of // synthetic frames introduced by lambdas & method handles return produced.replaceAll(":[1-9][0-9]*\\)", ":00)")
.replaceAll("/0x[0-9a-f]+\\.run", "/xxxxxxxx.run")
.replaceAll("/0x[0-9a-f]+\\.invoke", "/xxxxxxxx.invoke") // LFs may or may not be pre-generated, making frames differ
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
.replaceAll("Invokers\\$Holder", "LambdaForm\\$MH")
.replaceAll("MH\\.invoke", "MH/xxxxxxxx.invoke") // invoke frames may or may not have basic method type // information encoded for diagnostic purposes
.replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z_]+", "xx.invoke$1")
.replaceAll("\\$[0-9]+", "\\$??");
} else { return produced;
}
}
staticfinalclass Recorder { boolean found; // stop recording after main publicvoid recordSTE(long counter, StringBuilder s, StackFrame f) { if (found) return;
found = VerifyStackTrace.class.equals(f.getDeclaringClass()) && "main".equals(f.getMethodName());
String line = String.format("%d: %s", counter, f.toStackTraceElement());
s.append(line).append('\n');
System.out.println(line);
}
}
staticvoid test(TestCase test) {
System.out.println("\nTesting: " + test.description()); final AtomicLong counter = new AtomicLong(); final StringBuilder builder = new StringBuilder(); final Recorder recorder = new Recorder(); final Runnable run = () -> test.walker().forEach(
f -> recorder.recordSTE(counter.incrementAndGet(), builder, f)); final Handle handle = new Handle(run);
// We're not using lambda on purpose here. We want the anonymous // class on the stack.
PrivilegedAction<Object> pa = new PrivilegedAction<Object>() {
@Override public Object run() { try { return VerifyStackTrace.class
.getMethod("invoke", Runnable.class)
.invoke(null, handle);
} catch (NoSuchMethodException
| IllegalAccessException
| InvocationTargetException ex) {
System.out.flush(); thrownew RuntimeException(ex);
}
}
};
AccessController.doPrivileged(pa);
System.out.println("Main found: " + recorder.found); if (!Objects.equals(prepare(test.expected(), true), prepare(builder.toString(), true))) {
System.out.flush(); try { // sleep to make it less likely that System.out & System.err will // interleave. Thread.sleep(1000);
} catch (InterruptedException ex) {
}
System.err.println("\nUnexpected stack trace: "
+ "\n\n"
+ prepare(test.expected(), true)
+ "\n<-- actual -->\n"
+ prepare(builder.toString(), false)); thrownew RuntimeException("Unexpected stack trace for: " + test.description());
}
}
}
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.