Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 // An error class.
     18 class BadError extends Error {
     19     public BadError(String s) {
     20         super("This is bad by convention: " + s);
     21     }
     22 }
     23 
     24 // A class that throws BadError during static initialization.
     25 class BadInit {
     26     static int dummy;
     27     static {
     28         System.out.println("Static Init");
     29         if (true) {
     30             throw new BadError("BadInit");
     31         }
     32     }
     33 }
     34 
     35 // An error that doesn't have a <init>(String) method.
     36 class BadErrorNoStringInit extends Error {
     37     public BadErrorNoStringInit() {
     38         super("This is bad by convention");
     39     }
     40 }
     41 
     42 // A class that throws BadErrorNoStringInit during static initialization.
     43 class BadInitNoStringInit {
     44     static int dummy;
     45     static {
     46         System.out.println("Static BadInitNoStringInit");
     47         if (true) {
     48             throw new BadErrorNoStringInit();
     49         }
     50     }
     51 }
     52 
     53 // A class that throws BadError during static initialization, serving as a super class.
     54 class BadSuperClass {
     55  static int dummy;
     56  static {
     57      System.out.println("BadSuperClass Static Init");
     58      if (true) {
     59          throw new BadError("BadInit");
     60      }
     61  }
     62 }
     63 
     64 // A class that derives from BadSuperClass.
     65 class DerivedFromBadSuperClass extends BadSuperClass {
     66 }
     67 
     68 /**
     69  * Exceptions across method calls
     70  */
     71 public class Main {
     72     public static void exceptions_007() {
     73         try {
     74             catchAndRethrow();
     75         } catch (NullPointerException npe) {
     76             System.out.print("Got an NPE: ");
     77             System.out.println(npe.getMessage());
     78             npe.printStackTrace(System.out);
     79         }
     80     }
     81     public static void main(String args[]) {
     82         exceptions_007();
     83         exceptionsRethrowClassInitFailure();
     84         exceptionsRethrowClassInitFailureNoStringInit();
     85         exceptionsForSuperClassInitFailure();
     86         exceptionsInMultiDex();
     87     }
     88 
     89     private static void catchAndRethrow() {
     90         try {
     91             throwNullPointerException();
     92         } catch (NullPointerException npe) {
     93             NullPointerException npe2;
     94             npe2 = new NullPointerException("second throw");
     95             npe2.initCause(npe);
     96             throw npe2;
     97         }
     98     }
     99 
    100     private static void throwNullPointerException() {
    101         throw new NullPointerException("first throw");
    102     }
    103 
    104     private static void exceptionsRethrowClassInitFailure() {
    105         try {
    106             try {
    107                 BadInit.dummy = 1;
    108                 throw new IllegalStateException("Should not reach here.");
    109             } catch (BadError e) {
    110                 System.out.println(e);
    111             }
    112 
    113             // Check if it works a second time.
    114 
    115             try {
    116                 BadInit.dummy = 1;
    117                 throw new IllegalStateException("Should not reach here.");
    118             } catch (NoClassDefFoundError e) {
    119                 System.out.println(e);
    120                 System.out.println(e.getCause());
    121             }
    122         } catch (Exception error) {
    123             error.printStackTrace(System.out);
    124         }
    125     }
    126 
    127     private static void exceptionsRethrowClassInitFailureNoStringInit() {
    128         try {
    129             try {
    130                 BadInitNoStringInit.dummy = 1;
    131                 throw new IllegalStateException("Should not reach here.");
    132             } catch (BadErrorNoStringInit e) {
    133                 System.out.println(e);
    134             }
    135 
    136             // Check if it works a second time.
    137 
    138             try {
    139                 BadInitNoStringInit.dummy = 1;
    140                 throw new IllegalStateException("Should not reach here.");
    141             } catch (NoClassDefFoundError e) {
    142                 System.out.println(e);
    143                 System.out.println(e.getCause());
    144             }
    145         } catch (Exception error) {
    146             error.printStackTrace(System.out);
    147         }
    148     }
    149 
    150     private static void exceptionsForSuperClassInitFailure() {
    151         try {
    152             // Resolve DerivedFromBadSuperClass.
    153             BadSuperClass.dummy = 1;
    154             throw new IllegalStateException("Should not reach here.");
    155         } catch (BadError e) {
    156             System.out.println(e);
    157         } catch (Throwable t) {
    158             t.printStackTrace();
    159         }
    160         try {
    161             // Before splitting mirror::Class::kStatusError into
    162             // kStatusErrorUnresolved and kStatusErrorResolved,
    163             // this would trigger a
    164             //     CHECK(super_class->IsResolved())
    165             // failure in
    166             //     ClassLinker::LoadSuperAndInterfaces().
    167             // After the change we're getting either VerifyError
    168             // (for Optimizing) or NoClassDefFoundError wrapping
    169             // BadError (for interpreter or JIT).
    170             new DerivedFromBadSuperClass();
    171             throw new IllegalStateException("Should not reach here.");
    172         } catch (NoClassDefFoundError ncdfe) {
    173             if (!(ncdfe.getCause() instanceof BadError)) {
    174                 ncdfe.getCause().printStackTrace();
    175             }
    176         } catch (VerifyError e) {
    177         } catch (Throwable t) {
    178             t.printStackTrace();
    179         }
    180     }
    181 
    182     private static void exceptionsInMultiDex() {
    183         try {
    184             MultiDexBadInit.dummy = 1;
    185             throw new IllegalStateException("Should not reach here.");
    186         } catch (Error e) {
    187             System.out.println(e);
    188         } catch (Throwable t) {
    189             t.printStackTrace();
    190         }
    191         // Before splitting mirror::Class::kStatusError into
    192         // kStatusErrorUnresolved and kStatusErrorResolved,
    193         // the exception from wrapper 1 would have been
    194         // wrapped in NoClassDefFoundError but the exception
    195         // from wrapper 2 would have been unwrapped.
    196         try {
    197             MultiDexBadInitWrapper1.setDummy(1);
    198             throw new IllegalStateException("Should not reach here.");
    199         } catch (NoClassDefFoundError ncdfe) {
    200             System.out.println(ncdfe);
    201             System.out.println("  cause: " + ncdfe.getCause());
    202         } catch (Throwable t) {
    203             t.printStackTrace();
    204         }
    205         try {
    206             MultiDexBadInitWrapper2.setDummy(1);
    207             throw new IllegalStateException("Should not reach here.");
    208         } catch (NoClassDefFoundError ncdfe) {
    209             System.out.println(ncdfe);
    210             System.out.println("  cause: " + ncdfe.getCause());
    211         } catch (Throwable t) {
    212             t.printStackTrace();
    213         }
    214     }
    215 }
    216