Path: blob/master/test/jdk/java/lang/Throwable/StackTraceSerialization.java
41149 views
/*1* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.*;24import java.util.*;2526/*27* @test28* @bug 4202914 4363318 6991528 699887129* @summary Basic test of serialization of stack trace information30* @author Josh Bloch31*/3233public class StackTraceSerialization {34public static void main(String args[]) throws Exception {35testWithSetStackTrace();36testWithFillInStackTrace();37}3839private static void testWithSetStackTrace() {40StackTraceElement[] stackTrace = {new StackTraceElement("foo", "bar", "baz", -1)};4142Throwable t = new TestThrowable(true, false); // Immutable and empty stack43assertEmptyStackTrace(t);4445// Verify fillInStackTrace is now a no-op.46t.fillInStackTrace();47assertEmptyStackTrace(t);4849// Verify setStackTrace is now a no-op.50t.setStackTrace(stackTrace);51assertEmptyStackTrace(t);5253// Verify null-handling54try {55t.setStackTrace(null);56throw new RuntimeException("No NPE on a null stack trace.");57} catch(NullPointerException npe) {58assertEmptyStackTrace(t);59}6061try {62t.setStackTrace(new StackTraceElement[]{null});63throw new RuntimeException("No NPE on a null stack trace element.");64} catch(NullPointerException npe) {65assertEmptyStackTrace(t);66}6768if (!equal(t, reconstitute(t)))69throw new RuntimeException("Unequal Throwables with set stacktrace");7071Throwable t2 = new Throwable();72t2.setStackTrace(stackTrace);73if (!equal(t2, reconstitute(t2)))74throw new RuntimeException("Unequal Throwables with set stacktrace");7576}7778private static class TestThrowable extends Throwable {79public TestThrowable(boolean enableSuppression,80boolean writableStackTrace) {81super("the medium", null,82enableSuppression,83writableStackTrace);84}85}8687private static void assertEmptyStackTrace(Throwable t) {88if (t.getStackTrace().length != 0)89throw new AssertionError("Nonempty stacktrace.");90}9192private static void testWithFillInStackTrace() {93Throwable original = null;94try {95a();96} catch(HighLevelException e) {97original = e;98}99100if (!equal(original, reconstitute(original)))101throw new RuntimeException("Unequal Throwables with filled-in stacktrace");102}103104/**105* Serialize the argument and return the deserialized result.106*/107private static Throwable reconstitute(Throwable t) {108Throwable result = null;109try(ByteArrayOutputStream bout = new ByteArrayOutputStream();110ObjectOutputStream out = new ObjectOutputStream(bout)) {111out.writeObject(t);112out.flush();113try(ByteArrayInputStream bin =114new ByteArrayInputStream(bout.toByteArray());115ObjectInputStream in = new ObjectInputStream(bin)) {116result = (Throwable) in.readObject();117}118} catch(IOException | ClassNotFoundException e) {119throw new RuntimeException(e);120}121return result;122}123124/**125* Returns true if e1 and e2 have equal stack traces and their126* causes are recursively equal (by the same definition) and their127* suppressed exception information is equals. Returns false or128* throws NullPointerExeption otherwise.129*/130private static boolean equal(Throwable t1, Throwable t2) {131return t1==t2 ||132(Arrays.equals(t1.getStackTrace(), t2.getStackTrace()) &&133equal(t1.getCause(), t2.getCause()) &&134Objects.equals(t1.getSuppressed(), t2.getSuppressed()));135}136137static void a() throws HighLevelException {138try {139b();140} catch(MidLevelException e) {141throw new HighLevelException(e);142}143}144static void b() throws MidLevelException {145c();146}147static void c() throws MidLevelException {148try {149d();150} catch(LowLevelException e) {151throw new MidLevelException(e);152}153}154static void d() throws LowLevelException {155e();156}157static void e() throws LowLevelException {158throw new LowLevelException();159}160161private static final String OUR_CLASS = StackTraceSerialization.class.getName();162private static final String OUR_FILE_NAME = "StackTraceSerialization.java";163164private static void check(StackTraceElement e, String methodName, int n) {165if (!e.getClassName().equals(OUR_CLASS))166throw new RuntimeException("Class: " + e);167if (!e.getMethodName().equals(methodName))168throw new RuntimeException("Method name: " + e);169if (!e.getFileName().equals(OUR_FILE_NAME))170throw new RuntimeException("File name: " + e);171if (e.getLineNumber() != n)172throw new RuntimeException("Line number: " + e);173}174}175176class HighLevelException extends Exception {177HighLevelException(Throwable cause) { super(cause); }178}179180class MidLevelException extends Exception {181MidLevelException(Throwable cause) { super(cause); }182}183184class LowLevelException extends Exception {185}186187188