1e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes/* 2e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * Copyright (C) 2010 The Android Open Source Project 3e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * 4e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * you may not use this file except in compliance with the License. 6e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * You may obtain a copy of the License at 7e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * 8e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * 10e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * See the License for the specific language governing permissions and 14e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes * limitations under the License. 15e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes */ 16e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes 174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.java.lang; 18e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes 19e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughesimport java.io.PrintWriter; 20e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughesimport java.io.StringWriter; 218033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilsonimport java.util.Arrays; 22e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughesimport junit.framework.TestCase; 23b416ef5dc224630af2b9393a15ae120b27e4864aJesse Wilsonimport libcore.util.SerializationTester; 24e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes 25e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughespublic class ThrowableTest extends TestCase { 26e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes private static class NoStackTraceException extends Exception { 27e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes @Override 28e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes public synchronized Throwable fillInStackTrace() { 29e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes return null; 30e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes } 31e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes } 32e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes public void testNullStackTrace() { 33e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes try { 34e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes throw new NoStackTraceException(); 35e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes } catch (NoStackTraceException ex) { 36e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes // We used to throw NullPointerException when printing an exception with no stack trace. 37e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes ex.printStackTrace(new PrintWriter(new StringWriter())); 38e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes } 39e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes } 408033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 41c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes public void testNonWritableStackTrace() { 42c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes try { 43c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes // The 4th argument, writableStackTrace, is false... 44c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes throw new SuppressionsThrowable("hi", null, true, false); 45c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes } catch (Throwable th) { 46c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes assertEquals("hi", th.getMessage()); 47c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes 48c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes // We see an empty stack trace. 49c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes assertEquals(0, th.getStackTrace().length); 50c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes 51c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes // setStackTrace is a no-op. 52c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes th.setStackTrace(new StackTraceElement[] { new StackTraceElement("c", "m", "f", -2) }); 53c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes assertEquals(0, th.getStackTrace().length); 54c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes 55c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes // fillInStackTrace is a no-op. 56c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes th.fillInStackTrace(); 57c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes assertEquals(0, th.getStackTrace().length); 58c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes 59c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes // It's still possible to print an exception with writableStackTrace == false. 60c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes th.printStackTrace(new PrintWriter(new StringWriter())); 61c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes } 62c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes } 63c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes 648033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson private static class SuppressionsThrowable extends Throwable { 65c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes private static final long serialVersionUID = 202649043897209143L; 66c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes 678033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public SuppressionsThrowable(String detailMessage, Throwable throwable, 68c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes boolean enableSuppression, boolean writableStackTrace) { 69c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes super(detailMessage, throwable, enableSuppression, writableStackTrace); 708033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 718033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 728033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 738033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testAddSuppressed() { 748033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = new Throwable(); 758033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable); 768033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable suppressedA = new Throwable(); 778033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressedA); 788033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable, suppressedA); 798033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable suppressedB = new Throwable(); 808033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressedB); 818033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable, suppressedA, suppressedB); 828033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 838033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 848033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testAddDuplicateSuppressed() { 858033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = new Throwable(); 868033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable suppressedA = new Throwable(); 878033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressedA); 888033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressedA); 898033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressedA); 908033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable, suppressedA, suppressedA, suppressedA); 918033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 928033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 938033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testGetSuppressedReturnsCopy() { 948033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = new Throwable(); 958033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable suppressedA = new Throwable(); 968033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable suppressedB = new Throwable(); 978033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressedA); 988033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressedB); 998033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable[] mutable = throwable.getSuppressed(); 1008033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson mutable[0] = null; 1018033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson mutable[1] = null; 1028033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable, suppressedA, suppressedB); 1038033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1048033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1058033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testAddSuppressedWithSuppressionDisabled() { 106c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes Throwable throwable = new SuppressionsThrowable("foo", null, false, true); 1078033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable); 1088033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(new Throwable()); 1098033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable); 1108033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(new Throwable()); 1118033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(throwable); 1128033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1138033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1148033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testAddSuppressedSelf() { 1158033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = new Throwable(); 1168033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson try { 1178033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(throwable); 1188033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson fail(); 1198033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } catch (IllegalArgumentException expected) { 1208033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1218033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1228033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1238033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testAddSuppressedNull() { 1248033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = new Throwable(); 1258033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson try { 1268033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(null); 1278033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson fail(); 1288033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } catch (NullPointerException expected) { 1298033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1308033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1318033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1328033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testPrintStackTraceWithCause() { 1338033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = newThrowable("Throwable", "A", "B"); 1348033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.initCause(newThrowable("Cause", "A", "B", "C", "D")); 1358033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1368033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertEquals("java.lang.Throwable: Throwable\n" 1378033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassB.doB(ClassB.java:1)\n" 1388033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassA.doA(ClassA.java:0)\n" 1398033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "Caused by: java.lang.Throwable: Cause\n" 1408033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassD.doD(ClassD.java:3)\n" 1418033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassC.doC(ClassC.java:2)\n" 1428033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t... 2 more\n", printStackTraceToString(throwable)); 1438033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1448033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1458033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testPrintStackTraceWithCauseAndSuppressed() { 1468033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = newThrowable("Throwable", "A", "B"); 1478033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.initCause(newThrowable("Cause", "A", "B", "C", "D")); 1488033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(newThrowable("Suppressed", "A", "B", "E", "F")); 1498033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(newThrowable("Suppressed", "A", "B", "G", "H")); 1508033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1518033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertEquals("java.lang.Throwable: Throwable\n" 1528033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassB.doB(ClassB.java:1)\n" 1538033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassA.doA(ClassA.java:0)\n" 1548033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tSuppressed: java.lang.Throwable: Suppressed\n" 1558033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassF.doF(ClassF.java:3)\n" 1568033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassE.doE(ClassE.java:2)\n" 1578033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\t... 2 more\n" 1588033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tSuppressed: java.lang.Throwable: Suppressed\n" 1598033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassH.doH(ClassH.java:3)\n" 1608033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassG.doG(ClassG.java:2)\n" 1618033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\t... 2 more\n" 1628033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "Caused by: java.lang.Throwable: Cause\n" 1638033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassD.doD(ClassD.java:3)\n" 1648033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassC.doC(ClassC.java:2)\n" 1658033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t... 2 more\n", printStackTraceToString(throwable)); 1668033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 1678033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1688033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testPrintStackTraceWithEverything() { 1698033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = newThrowable("Throwable", "A", "B"); 1708033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable cause = newThrowable("Cause", "A", "B", "C", "D"); 1718033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable suppressed = newThrowable("Suppressed", "A", "B", "E", "F"); 1728033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1738033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(suppressed); 1748033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson suppressed.addSuppressed(newThrowable("Suppressed/Suppressed", "A", "B", "E", "G")); 1758033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson suppressed.initCause(newThrowable("Suppressed/Cause", "A", "B", "E", "H")); 1768033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1778033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.initCause(cause); 1788033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson cause.addSuppressed(newThrowable("Cause/Suppressed", "A", "B", "C", "I")); 1798033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson cause.initCause(newThrowable("Cause/Cause", "A", "B", "C", "J")); 1808033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 1818033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertEquals("java.lang.Throwable: Throwable\n" 1828033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassB.doB(ClassB.java:1)\n" 1838033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassA.doA(ClassA.java:0)\n" 1848033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tSuppressed: java.lang.Throwable: Suppressed\n" 1858033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassF.doF(ClassF.java:3)\n" 1868033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassE.doE(ClassE.java:2)\n" 1878033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\t... 2 more\n" 1888033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tSuppressed: java.lang.Throwable: Suppressed/Suppressed\n" 1898033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\t\tat ClassG.doG(ClassG.java:3)\n" 1908033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\t\t... 3 more\n" 1918033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tCaused by: java.lang.Throwable: Suppressed/Cause\n" 1928033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassH.doH(ClassH.java:3)\n" 1938033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\t... 3 more\n" 1948033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "Caused by: java.lang.Throwable: Cause\n" 1958033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassD.doD(ClassD.java:3)\n" 1968033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassC.doC(ClassC.java:2)\n" 1978033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t... 2 more\n" 1988033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tSuppressed: java.lang.Throwable: Cause/Suppressed\n" 1998033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\tat ClassI.doI(ClassI.java:3)\n" 2008033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t\t... 3 more\n" 2018033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "Caused by: java.lang.Throwable: Cause/Cause\n" 2028033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\tat ClassJ.doJ(ClassJ.java:3)\n" 2038033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "\t... 3 more\n", printStackTraceToString(throwable)); 2048033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2058033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 2068033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testSetStackTraceWithNullElement() { 2078033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = new Throwable(); 2088033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson try { 2098033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.setStackTrace(new StackTraceElement[]{ null }); 2108033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson fail(); 2118033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } catch (NullPointerException expected) { 2128033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2138033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2148033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 2158033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testCauseSerialization() { 2168033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson String s = "aced0005737200136a6176612e6c616e672e5468726f7761626c65d5c635273977b8cb0300034c0" 2178033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "00563617573657400154c6a6176612f6c616e672f5468726f7761626c653b4c000d64657461696c4" 2188033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "d6573736167657400124c6a6176612f6c616e672f537472696e673b5b000a737461636b547261636" 2198033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "574001e5b4c6a6176612f6c616e672f537461636b5472616365456c656d656e743b78707371007e0" 2208033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "00071007e000574000543617573657572001e5b4c6a6176612e6c616e672e537461636b547261636" 2218033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "5456c656d656e743b02462a3c3cfd22390200007870000000047372001b6a6176612e6c616e672e5" 2228033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "37461636b5472616365456c656d656e746109c59a2636dd8502000449000a6c696e654e756d62657" 2238033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "24c000e6465636c6172696e67436c61737371007e00024c000866696c654e616d6571007e00024c0" 2248033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "00a6d6574686f644e616d6571007e0002787000000003740006436c6173734474000b436c6173734" 2258033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "42e6a617661740003646f447371007e000900000002740006436c6173734374000b436c617373432" 2268033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "e6a617661740003646f437371007e000900000001740006436c6173734274000b436c617373422e6" 2278033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "a617661740003646f427371007e000900000000740006436c6173734174000b436c617373412e6a6" 2288033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "17661740003646f41787400095468726f7761626c657571007e0007000000027371007e000900000" 2298033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "001740006436c6173734274000b436c617373422e6a617661740003646f427371007e00090000000" 2308033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "0740006436c6173734174000b436c617373412e6a617661740003646f4178"; 2318033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = newThrowable("Throwable", "A", "B"); 2328033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.initCause(newThrowable("Cause", "A", "B", "C", "D")); 2338033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSerialized(throwable, s); 2348033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2358033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 2368033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testSuppressedSerialization() { 2378033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson String s = "aced0005737200136a6176612e6c616e672e5468726f7761626c65d5c635273977b8cb0300044c0" 2388033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "00563617573657400154c6a6176612f6c616e672f5468726f7761626c653b4c000d64657461696c4" 2398033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "d6573736167657400124c6a6176612f6c616e672f537472696e673b5b000a737461636b547261636" 2408033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "574001e5b4c6a6176612f6c616e672f537461636b5472616365456c656d656e743b4c00147375707" 2418033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "0726573736564457863657074696f6e737400104c6a6176612f7574696c2f4c6973743b787071007" 2428033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "e000574000a53657269616c697a65647572001e5b4c6a6176612e6c616e672e537461636b5472616" 2438033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "365456c656d656e743b02462a3c3cfd22390200007870000000027372001b6a6176612e6c616e672" 2448033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "e537461636b5472616365456c656d656e746109c59a2636dd8502000449000a6c696e654e756d626" 2458033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "5724c000e6465636c6172696e67436c61737371007e00024c000866696c654e616d6571007e00024" 2468033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "c000a6d6574686f644e616d6571007e0002787000000001740006436c6173734274000b436c61737" 2478033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "3422e6a617661740003646f427371007e000900000000740006436c6173734174000b436c6173734" 2488033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "12e6a617661740003646f41737200136a6176612e7574696c2e41727261794c6973747881d21d99c" 2498033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "7619d03000149000473697a657870000000017704000000017371007e000071007e001474000a537" 2508033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "570707265737365647571007e0007000000047371007e000900000003740006436c6173734474000" 2518033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "b436c617373442e6a617661740003646f447371007e000900000002740006436c6173734374000b4" 2528033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "36c617373432e6a617661740003646f437371007e000900000001740006436c6173734274000b436" 2538033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "c617373422e6a617661740003646f427371007e000900000000740006436c6173734174000b436c6" 2548033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "17373412e6a617661740003646f41737200266a6176612e7574696c2e436f6c6c656374696f6e732" 2558033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "4556e6d6f6469666961626c654c697374fc0f2531b5ec8e100200014c00046c69737471007e00047" 2568033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "872002c6a6176612e7574696c2e436f6c6c656374696f6e7324556e6d6f6469666961626c65436f6" 2578033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "c6c656374696f6e19420080cb5ef71e0200014c0001637400164c6a6176612f7574696c2f436f6c6" 2588033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "c656374696f6e3b78707371007e0012000000007704000000007871007e002b787878"; 2598033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable throwable = newThrowable("Serialized", "A", "B"); 2608033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.addSuppressed(newThrowable("Suppressed", "A", "B", "C", "D")); 2618033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSerialized(throwable, s); 2628033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2638033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 2648033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testDisableSuppressionSerialization() { 2658033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson String s = "aced0005737200356c6962636f72652e6a6176612e6c616e672e5468726f7761626c65546573742" 2668033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "45375707072657373696f6e735468726f7761626c6502cff43b5390d137020000787200136a61766" 2678033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "12e6c616e672e5468726f7761626c65d5c635273977b8cb0300044c000563617573657400154c6a6" 2688033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "176612f6c616e672f5468726f7761626c653b4c000d64657461696c4d6573736167657400124c6a6" 2698033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "176612f6c616e672f537472696e673b5b000a737461636b547261636574001e5b4c6a6176612f6c6" 2708033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "16e672f537461636b5472616365456c656d656e743b4c00147375707072657373656445786365707" 2718033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "4696f6e737400104c6a6176612f7574696c2f4c6973743b787070740003666f6f7572001e5b4c6a6" 2728033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "176612e6c616e672e537461636b5472616365456c656d656e743b02462a3c3cfd223902000078700" 2738033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "00000007078"; 274c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes Throwable throwable = new SuppressionsThrowable("foo", null, false, true); 2758033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.setStackTrace(new StackTraceElement[0]); 276b416ef5dc224630af2b9393a15ae120b27e4864aJesse Wilson new SerializationTester<Throwable>(throwable, s) { 2778033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson @Override protected boolean equals(Throwable a, Throwable b) { 2788033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson return printStackTraceToString(a).equals(printStackTraceToString(b)); 2798033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2808033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson @Override protected void verify(Throwable deserialized) { 2818033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson // the suppressed exception is silently discarded 2828033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson deserialized.addSuppressed(newThrowable("Suppressed")); 2838033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(deserialized); 2848033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2858033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson }.test(); 2868033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 2878033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 2888033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson public void testEnableSuppressionSerialization() { 2898033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson String s = "aced0005737200356c6962636f72652e6a6176612e6c616e672e5468726f7761626c65546573742" 2908033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "45375707072657373696f6e735468726f7761626c6502cff43b5390d137020000787200136a61766" 2918033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "12e6c616e672e5468726f7761626c65d5c635273977b8cb0300044c000563617573657400154c6a6" 2928033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "176612f6c616e672f5468726f7761626c653b4c000d64657461696c4d6573736167657400124c6a6" 2938033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "176612f6c616e672f537472696e673b5b000a737461636b547261636574001e5b4c6a6176612f6c6" 2948033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "16e672f537461636b5472616365456c656d656e743b4c00147375707072657373656445786365707" 2958033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "4696f6e737400104c6a6176612f7574696c2f4c6973743b787070740003666f6f7572001e5b4c6a6" 2968033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "176612e6c616e672e537461636b5472616365456c656d656e743b02462a3c3cfd223902000078700" 2978033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "0000000737200266a6176612e7574696c2e436f6c6c656374696f6e7324556e6d6f6469666961626" 2988033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "c654c697374fc0f2531b5ec8e100200014c00046c69737471007e00057872002c6a6176612e75746" 2998033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "96c2e436f6c6c656374696f6e7324556e6d6f6469666961626c65436f6c6c656374696f6e1942008" 3008033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "0cb5ef71e0200014c0001637400164c6a6176612f7574696c2f436f6c6c656374696f6e3b7870737" 3018033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "200136a6176612e7574696c2e41727261794c6973747881d21d99c7619d03000149000473697a657" 3028033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson + "870000000007704000000007871007e000f78"; 303c2f2aaaae219c69d50eee6549d507c91e9a08519Elliott Hughes Throwable throwable = new SuppressionsThrowable("foo", null, true, true); 3048033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.setStackTrace(new StackTraceElement[0]); 305b416ef5dc224630af2b9393a15ae120b27e4864aJesse Wilson new SerializationTester<Throwable>(throwable, s) { 3068033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson @Override protected boolean equals(Throwable a, Throwable b) { 3078033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson return printStackTraceToString(a).equals(printStackTraceToString(b)); 3088033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3098033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson @Override protected void verify(Throwable deserialized) { 3108033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson // the suppressed exception is permitted 3118033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable suppressed = newThrowable("Suppressed"); 3128033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson deserialized.addSuppressed(suppressed); 3138033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertSuppressed(deserialized, suppressed); 3148033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3158033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson }.test(); 3168033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3178033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 3188033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson private void assertSerialized(final Throwable throwable, String golden) { 319b416ef5dc224630af2b9393a15ae120b27e4864aJesse Wilson new SerializationTester<Throwable>(throwable, golden) { 3208033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson @Override protected boolean equals(Throwable a, Throwable b) { 3218033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson return printStackTraceToString(a).equals(printStackTraceToString(b)); 3228033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3238033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson }.test(); 3248033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3258033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 3268033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson private Throwable newThrowable(String message, String... stackTraceElements) { 3278033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson StackTraceElement[] array = new StackTraceElement[stackTraceElements.length]; 3288033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson for (int i = 0; i < stackTraceElements.length; i++) { 3298033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson String s = stackTraceElements[i]; 3308033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson array[stackTraceElements.length - 1 - i] 3318033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson = new StackTraceElement("Class" + s, "do" + s, "Class" + s + ".java", i); 3328033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3338033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson Throwable result = new Throwable(message); 3348033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson result.setStackTrace(array); 3358033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson return result; 3368033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3378033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 3388033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson private String printStackTraceToString(Throwable throwable) { 3398033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson StringWriter writer = new StringWriter(); 3408033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson throwable.printStackTrace(new PrintWriter(writer)); 3418033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson return writer.toString(); 3428033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 3438033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson 3448033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson private void assertSuppressed(Throwable throwable, Throwable... expectedSuppressed) { 3458033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson assertEquals(Arrays.asList(throwable.getSuppressed()), Arrays.asList(expectedSuppressed)); 3468033ba2bd4b8eab11e67738ba4d1390e1fb72111Jesse Wilson } 347e8ca15fac603d1adb0fd9007ea6343584a15db67Elliott Hughes} 348