8233745: [JVMCI] TranslatedException should serialize classloader and module info
Reviewed-by: kvn, dnsimon
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java Sat Nov 09 11:48:37 2019 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java Sat Nov 09 10:27:53 2019 -0800
@@ -122,7 +122,7 @@
* a single exception is:
*
* <pre>
- * <exception class name> '|' <exception message> '|' <stack size> '|' [<class> '|' <method> '|' <file> '|' <line> '|' ]*
+ * <exception class name> '|' <exception message> '|' <stack size> '|' [ <classLoader> '|' <module> '|' <moduleVersion> '|' <class> '|' <method> '|' <file> '|' <line> '|' ]*
* </pre>
*
* Each exception is encoded before the exception it causes.
@@ -149,8 +149,10 @@
for (int i = 0; i < stackTrace.length; i++) {
StackTraceElement frame = stackTrace[i];
if (frame != null) {
- enc.format("%s|%s|%s|%d|", frame.getClassName(), frame.getMethodName(),
- encodedString(frame.getFileName()), frame.getLineNumber());
+ enc.format("%s|%s|%s|%s|%s|%s|%d|", encodedString(frame.getClassLoaderName()),
+ encodedString(frame.getModuleName()), encodedString(frame.getModuleVersion()),
+ frame.getClassName(), frame.getMethodName(),
+ encodedString(frame.getFileName()), frame.getLineNumber());
}
}
}
@@ -206,14 +208,26 @@
StackTraceElement[] suffix = getStackTraceSuffix();
StackTraceElement[] stackTrace = new StackTraceElement[stackTraceDepth + suffix.length];
for (int j = 0; j < stackTraceDepth; j++) {
+ String classLoaderName = parts[i++];
+ String moduleName = parts[i++];
+ String moduleVersion = parts[i++];
String className = parts[i++];
String methodName = parts[i++];
String fileName = parts[i++];
int lineNumber = Integer.parseInt(parts[i++]);
+ if (classLoaderName.isEmpty()) {
+ classLoaderName = null;
+ }
+ if (moduleName.isEmpty()) {
+ moduleName = null;
+ }
+ if (moduleVersion.isEmpty()) {
+ moduleVersion = null;
+ }
if (fileName.isEmpty()) {
fileName = null;
}
- stackTrace[j] = new StackTraceElement(className, methodName, fileName, lineNumber);
+ stackTrace[j] = new StackTraceElement(classLoaderName, moduleName, moduleVersion, className, methodName, fileName, lineNumber);
}
System.arraycopy(suffix, 0, stackTrace, stackTraceDepth, suffix.length);
throwable.setStackTrace(stackTrace);
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestTranslatedException.java Sat Nov 09 11:48:37 2019 +0000
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestTranslatedException.java Sat Nov 09 10:27:53 2019 -0800
@@ -26,7 +26,6 @@
* @requires vm.jvmci
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot:open
* @library /compiler/jvmci/jdk.vm.ci.hotspot.test/src
- * @ignore 8233745
* @run testng/othervm
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler
* jdk.vm.ci.hotspot.test.TestTranslatedException
@@ -43,15 +42,6 @@
import org.testng.annotations.Test;
public class TestTranslatedException {
-
- private static String printToString(Throwable throwable) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try (PrintStream ps = new PrintStream(baos)) {
- throwable.printStackTrace(ps);
- }
- return baos.toString();
- }
-
@SuppressWarnings("serial")
public static class Untranslatable extends RuntimeException {
public Untranslatable(String message, Throwable cause) {
@@ -74,15 +64,47 @@
for (int i = 0; i < 10; i++) {
throwable = new ExceptionInInitializerError(new InvocationTargetException(new RuntimeException(String.valueOf(i), throwable), "invoke"));
}
- String before = printToString(throwable);
String encoding = (String) encode.invoke(null, throwable);
Throwable decoded = (Throwable) decode.invoke(null, encoding);
- String after = printToString(decoded);
+ assertThrowableEquals(throwable, decoded);
+ }
- after = after.replace(
- "jdk.vm.ci.hotspot.TranslatedException: [java.lang.ClassNotFoundException: jdk/vm/ci/hotspot/test/TestTranslatedException$Untranslatable]",
- "jdk.vm.ci.hotspot.test.TestTranslatedException$Untranslatable: test exception");
-
- Assert.assertEquals(before, after);
+ private static void assertThrowableEquals(Throwable original, Throwable decoded) {
+ try {
+ Assert.assertEquals(original == null, decoded == null);
+ while (original != null) {
+ if (Untranslatable.class.equals(original.getClass())) {
+ Assert.assertEquals("jdk.vm.ci.hotspot.TranslatedException", decoded.getClass().getName());
+ Assert.assertEquals("[java.lang.ClassNotFoundException: jdk/vm/ci/hotspot/test/TestTranslatedException$Untranslatable]", decoded.getMessage());
+ Assert.assertEquals("test exception", original.getMessage());
+ } else {
+ Assert.assertEquals(original.getClass().getName(), decoded.getClass().getName());
+ Assert.assertEquals(original.getMessage(), decoded.getMessage());
+ }
+ StackTraceElement[] originalStack = original.getStackTrace();
+ StackTraceElement[] decodedStack = decoded.getStackTrace();
+ Assert.assertEquals(originalStack.length, decodedStack.length);
+ for (int i = 0, n = originalStack.length; i < n; ++i) {
+ StackTraceElement originalStackElement = originalStack[i];
+ StackTraceElement decodedStackElement = decodedStack[i];
+ Assert.assertEquals(originalStackElement.getClassLoaderName(), decodedStackElement.getClassLoaderName());
+ Assert.assertEquals(originalStackElement.getModuleName(), decodedStackElement.getModuleName());
+ Assert.assertEquals(originalStackElement.getClassName(), decodedStackElement.getClassName());
+ Assert.assertEquals(originalStackElement.getMethodName(), decodedStackElement.getMethodName());
+ Assert.assertEquals(originalStackElement.getFileName(), decodedStackElement.getFileName());
+ Assert.assertEquals(originalStackElement.getLineNumber(), decodedStackElement.getLineNumber());
+ }
+ original = original.getCause();
+ decoded = decoded.getCause();
+ }
+ } catch (AssertionError e) {
+ System.err.println("original:[");
+ original.printStackTrace(System.err);
+ System.err.println("]");
+ System.err.println("decoded:[");
+ original.printStackTrace(System.err);
+ System.err.println("]");
+ throw e;
+ }
}
}