1 /*
   2  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.*;
  25 import java.util.*;
  26 
  27 /*
  28  * @test
  29  * @bug     6911258 6962571 6963622 6991528
  30  * @summary Basic tests of suppressed exceptions
  31  * @author  Joseph D. Darcy
  32  */
  33 
  34 public class SuppressedExceptions {
  35     private static String message = "Bad suppressed exception information";
  36 
  37     public static void main(String... args) throws Exception {
  38         noSelfSuppression();
  39         basicSupressionTest();
  40         serializationTest();
  41         selfReference();
  42         noModification();
  43     }
  44 
  45     private static void noSelfSuppression() {
  46         Throwable throwable = new Throwable();
  47         try {
  48             throwable.addSuppressed(throwable);
  49             throw new RuntimeException("IllegalArgumentException for self-suppresion not thrown.");
  50         } catch (IllegalArgumentException iae) {
  51             ; // Expected
  52         }
  53 
  54         throwable.addSuppressed(null); // Immutable suppression list
  55         try {
  56             throwable.addSuppressed(throwable);
  57             throw new RuntimeException("IllegalArgumentException for self-suppresion not thrown.");
  58         } catch (IllegalArgumentException iae) {
  59             ; // Expected
  60         }
  61     }
  62 
  63     private static void basicSupressionTest() {
  64         Throwable throwable = new Throwable();
  65         RuntimeException suppressed = new RuntimeException("A suppressed exception.");
  66         AssertionError repressed  = new AssertionError("A repressed error.");
  67 
  68         Throwable[] t0 = throwable.getSuppressed();
  69         if (t0.length != 0) {
  70             throw new RuntimeException(message);
  71         }
  72         throwable.printStackTrace();
  73 
  74         throwable.addSuppressed(suppressed);
  75         Throwable[] t1 = throwable.getSuppressed();
  76         if (t1.length != 1 ||
  77             t1[0] != suppressed) {throw new RuntimeException(message);
  78         }
  79         throwable.printStackTrace();
  80 
  81         throwable.addSuppressed(repressed);
  82         Throwable[] t2 = throwable.getSuppressed();
  83         if (t2.length != 2 ||
  84             t2[0] != suppressed ||
  85             t2[1] != repressed) {
  86             throw new RuntimeException(message);
  87         }
  88         throwable.printStackTrace();
  89     }
  90 
  91     private static void serializationTest() throws Exception {
  92         /*
  93          * Bytes of the serial form of
  94          *
  95          * (new Throwable())setStackTrace(new StackTraceElement[0])
  96          *
  97          * from JDK 6; suppressedException field will be missing and
  98          * thus default to null upon deserialization.
  99          */
 100         byte[] bytes = {
 101             (byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x13,
 102             (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e,
 103             (byte)0x67, (byte)0x2e, (byte)0x54, (byte)0x68, (byte)0x72, (byte)0x6f, (byte)0x77, (byte)0x61,
 104             (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0xd5, (byte)0xc6, (byte)0x35, (byte)0x27, (byte)0x39,
 105             (byte)0x77, (byte)0xb8, (byte)0xcb, (byte)0x03, (byte)0x00, (byte)0x03, (byte)0x4c, (byte)0x00,
 106             (byte)0x05, (byte)0x63, (byte)0x61, (byte)0x75, (byte)0x73, (byte)0x65, (byte)0x74, (byte)0x00,
 107             (byte)0x15, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
 108             (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x54, (byte)0x68, (byte)0x72, (byte)0x6f,
 109             (byte)0x77, (byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x3b, (byte)0x4c, (byte)0x00,
 110             (byte)0x0d, (byte)0x64, (byte)0x65, (byte)0x74, (byte)0x61, (byte)0x69, (byte)0x6c, (byte)0x4d,
 111             (byte)0x65, (byte)0x73, (byte)0x73, (byte)0x61, (byte)0x67, (byte)0x65, (byte)0x74, (byte)0x00,
 112             (byte)0x12, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
 113             (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69,
 114             (byte)0x6e, (byte)0x67, (byte)0x3b, (byte)0x5b, (byte)0x00, (byte)0x0a, (byte)0x73, (byte)0x74,
 115             (byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65,
 116             (byte)0x74, (byte)0x00, (byte)0x1e, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76,
 117             (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53,
 118             (byte)0x74, (byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63,
 119             (byte)0x65, (byte)0x45, (byte)0x6c, (byte)0x65, (byte)0x6d, (byte)0x65, (byte)0x6e, (byte)0x74,
 120             (byte)0x3b, (byte)0x78, (byte)0x70, (byte)0x71, (byte)0x00, (byte)0x7e, (byte)0x00, (byte)0x04,
 121             (byte)0x70, (byte)0x75, (byte)0x72, (byte)0x00, (byte)0x1e, (byte)0x5b, (byte)0x4c, (byte)0x6a,
 122             (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
 123             (byte)0x2e, (byte)0x53, (byte)0x74, (byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72,
 124             (byte)0x61, (byte)0x63, (byte)0x65, (byte)0x45, (byte)0x6c, (byte)0x65, (byte)0x6d, (byte)0x65,
 125             (byte)0x6e, (byte)0x74, (byte)0x3b, (byte)0x02, (byte)0x46, (byte)0x2a, (byte)0x3c, (byte)0x3c,
 126             (byte)0xfd, (byte)0x22, (byte)0x39, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
 127             (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0xac, (byte)0xed, (byte)0x00,
 128             (byte)0x05, (byte)0x73, (byte)0x72, (byte)0x00, (byte)0x13, (byte)0x6a, (byte)0x61, (byte)0x76,
 129             (byte)0x61, (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x54,
 130             (byte)0x68, (byte)0x72, (byte)0x6f, (byte)0x77, (byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65,
 131             (byte)0xd5, (byte)0xc6, (byte)0x35, (byte)0x27, (byte)0x39, (byte)0x77, (byte)0xb8, (byte)0xcb,
 132             (byte)0x03, (byte)0x00, (byte)0x03, (byte)0x4c, (byte)0x00, (byte)0x05, (byte)0x63, (byte)0x61,
 133             (byte)0x75, (byte)0x73, (byte)0x65, (byte)0x74, (byte)0x00, (byte)0x15, (byte)0x4c, (byte)0x6a,
 134             (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
 135             (byte)0x2f, (byte)0x54, (byte)0x68, (byte)0x72, (byte)0x6f, (byte)0x77, (byte)0x61, (byte)0x62,
 136             (byte)0x6c, (byte)0x65, (byte)0x3b, (byte)0x4c, (byte)0x00, (byte)0x0d, (byte)0x64, (byte)0x65,
 137             (byte)0x74, (byte)0x61, (byte)0x69, (byte)0x6c, (byte)0x4d, (byte)0x65, (byte)0x73, (byte)0x73,
 138             (byte)0x61, (byte)0x67, (byte)0x65, (byte)0x74, (byte)0x00, (byte)0x12, (byte)0x4c, (byte)0x6a,
 139             (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x6e, (byte)0x67, (byte)0x3b,
 140             (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69,
 141             (byte)0x5b, (byte)0x00, (byte)0x0a, (byte)0x73, (byte)0x74, (byte)0x61, (byte)0x63, (byte)0x6b,
 142             (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65, (byte)0x74, (byte)0x00, (byte)0x1e,
 143             (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
 144             (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x61, (byte)0x63,
 145             (byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65, (byte)0x45, (byte)0x6c,
 146             (byte)0x65, (byte)0x6d, (byte)0x65, (byte)0x6e, (byte)0x74, (byte)0x3b, (byte)0x78, (byte)0x70,
 147             (byte)0x71, (byte)0x00, (byte)0x7e, (byte)0x00, (byte)0x04, (byte)0x70, (byte)0x75, (byte)0x72,
 148             (byte)0x00, (byte)0x1e, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61,
 149             (byte)0x2e, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2e, (byte)0x53, (byte)0x74,
 150             (byte)0x61, (byte)0x63, (byte)0x6b, (byte)0x54, (byte)0x72, (byte)0x61, (byte)0x63, (byte)0x65,
 151             (byte)0x45, (byte)0x6c, (byte)0x65, (byte)0x6d, (byte)0x65, (byte)0x6e, (byte)0x74, (byte)0x3b,
 152             (byte)0x02, (byte)0x46, (byte)0x2a, (byte)0x3c, (byte)0x3c, (byte)0xfd, (byte)0x22, (byte)0x39,
 153             (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x78, (byte)0x70,
 154         };
 155 
 156         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
 157         ObjectInputStream ois = new ObjectInputStream(bais);
 158 
 159         Object o = ois.readObject();
 160         Throwable throwable = (Throwable) o;
 161 
 162         System.err.println("TESTING SERIALIZED EXCEPTION");
 163 
 164         Throwable[] t0 = throwable.getSuppressed();
 165         if (t0.length != 0) { // Will fail if t0 is null.
 166             throw new RuntimeException(message);
 167         }
 168         throwable.printStackTrace();
 169     }
 170 
 171     private static void selfReference() {
 172         Throwable throwable1 = new RuntimeException();
 173         Throwable throwable2 = new AssertionError();
 174         throwable1.initCause(throwable2);
 175         throwable2.initCause(throwable1);
 176 
 177         throwable1.printStackTrace();
 178 
 179         throwable1.addSuppressed(throwable2);
 180         throwable2.addSuppressed(throwable1);
 181 
 182         throwable1.printStackTrace();
 183     }
 184 
 185     private static void noModification() {
 186         Throwable t = new Throwable();
 187         t.addSuppressed(null);
 188 
 189         Throwable[] t0 = t.getSuppressed();
 190         if (t0.length != 0)
 191             throw new RuntimeException("Bad nonzero length of suppressed exceptions.");
 192 
 193         t.addSuppressed(new ArithmeticException());
 194 
 195         // Make sure a suppressed exception did *not* get added.
 196         t0 = t.getSuppressed();
 197         if (t0.length != 0)
 198             throw new RuntimeException("Bad nonzero length of suppressed exceptions.");
 199     }
 200 }