xref: /aosp_15_r20/art/test/084-class-init/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2010 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker public class Main {
18*795d594fSAndroid Build Coastguard Worker     static {
staticMethodCalledByClinit()19*795d594fSAndroid Build Coastguard Worker         staticMethodCalledByClinit();
20*795d594fSAndroid Build Coastguard Worker     }
21*795d594fSAndroid Build Coastguard Worker 
staticMethodCalledByClinit()22*795d594fSAndroid Build Coastguard Worker     private static void staticMethodCalledByClinit() {
23*795d594fSAndroid Build Coastguard Worker         // Test that DeliverException works when we need to unwind to a handler -- this method --
24*795d594fSAndroid Build Coastguard Worker         // that is currently a resolution stub because it's running on behalf of <clinit>.
25*795d594fSAndroid Build Coastguard Worker         try {
26*795d594fSAndroid Build Coastguard Worker             throwDuringClinit();
27*795d594fSAndroid Build Coastguard Worker             System.out.println("didn't throw!");
28*795d594fSAndroid Build Coastguard Worker         } catch (NullPointerException ex) {
29*795d594fSAndroid Build Coastguard Worker             System.out.println("caught exception thrown during clinit");
30*795d594fSAndroid Build Coastguard Worker         }
31*795d594fSAndroid Build Coastguard Worker     }
32*795d594fSAndroid Build Coastguard Worker 
throwDuringClinit()33*795d594fSAndroid Build Coastguard Worker     private static void throwDuringClinit() {
34*795d594fSAndroid Build Coastguard Worker         throw new NullPointerException();
35*795d594fSAndroid Build Coastguard Worker     }
36*795d594fSAndroid Build Coastguard Worker 
main(String[] args)37*795d594fSAndroid Build Coastguard Worker     public static void main(String[] args) {
38*795d594fSAndroid Build Coastguard Worker         checkExceptions();
39*795d594fSAndroid Build Coastguard Worker         checkTiming();
40*795d594fSAndroid Build Coastguard Worker         checkStaticMethodInvokeAfterFailedClinit();
41*795d594fSAndroid Build Coastguard Worker     }
42*795d594fSAndroid Build Coastguard Worker 
sleep(int msec)43*795d594fSAndroid Build Coastguard Worker     public static void sleep(int msec) {
44*795d594fSAndroid Build Coastguard Worker         try {
45*795d594fSAndroid Build Coastguard Worker             Thread.sleep(msec);
46*795d594fSAndroid Build Coastguard Worker         } catch (InterruptedException ie) {
47*795d594fSAndroid Build Coastguard Worker             System.out.println("sleep interrupted");
48*795d594fSAndroid Build Coastguard Worker         }
49*795d594fSAndroid Build Coastguard Worker     }
50*795d594fSAndroid Build Coastguard Worker 
checkExceptions()51*795d594fSAndroid Build Coastguard Worker     static void checkExceptions() {
52*795d594fSAndroid Build Coastguard Worker         try {
53*795d594fSAndroid Build Coastguard Worker             System.out.println(PartialInit.FIELD0);
54*795d594fSAndroid Build Coastguard Worker             System.out.println("Construction of PartialInit succeeded unexpectedly");
55*795d594fSAndroid Build Coastguard Worker         } catch (ExceptionInInitializerError eiie) {
56*795d594fSAndroid Build Coastguard Worker             System.out.println("Got expected EIIE for FIELD0");
57*795d594fSAndroid Build Coastguard Worker         }
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker         try {
60*795d594fSAndroid Build Coastguard Worker             System.out.println(PartialInit.FIELD0);
61*795d594fSAndroid Build Coastguard Worker             System.out.println("Load of FIELD0 succeeded unexpectedly");
62*795d594fSAndroid Build Coastguard Worker         } catch (NoClassDefFoundError ncdfe) {
63*795d594fSAndroid Build Coastguard Worker             System.out.println("Got expected NCDFE for FIELD0");
64*795d594fSAndroid Build Coastguard Worker         }
65*795d594fSAndroid Build Coastguard Worker         try {
66*795d594fSAndroid Build Coastguard Worker             System.out.println(PartialInit.FIELD1);
67*795d594fSAndroid Build Coastguard Worker             System.out.println("Load of FIELD1 succeeded unexpectedly");
68*795d594fSAndroid Build Coastguard Worker         } catch (NoClassDefFoundError ncdfe) {
69*795d594fSAndroid Build Coastguard Worker             System.out.println("Got expected NCDFE for FIELD1");
70*795d594fSAndroid Build Coastguard Worker         }
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker         try {
73*795d594fSAndroid Build Coastguard Worker             System.out.println(Exploder.FIELD);
74*795d594fSAndroid Build Coastguard Worker             System.out.println("Load of FIELD succeeded unexpectedly");
75*795d594fSAndroid Build Coastguard Worker         } catch (AssertionError expected) {
76*795d594fSAndroid Build Coastguard Worker             System.out.println("Got expected '" + expected.getMessage() + "' from Exploder");
77*795d594fSAndroid Build Coastguard Worker         }
78*795d594fSAndroid Build Coastguard Worker     }
79*795d594fSAndroid Build Coastguard Worker 
checkTiming()80*795d594fSAndroid Build Coastguard Worker     static void checkTiming() {
81*795d594fSAndroid Build Coastguard Worker         FieldThread fieldThread = new FieldThread();
82*795d594fSAndroid Build Coastguard Worker         MethodThread methodThread = new MethodThread();
83*795d594fSAndroid Build Coastguard Worker 
84*795d594fSAndroid Build Coastguard Worker         fieldThread.start();
85*795d594fSAndroid Build Coastguard Worker         methodThread.start();
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker         /* start class init */
88*795d594fSAndroid Build Coastguard Worker         IntHolder zero = SlowInit.FIELD0;
89*795d594fSAndroid Build Coastguard Worker 
90*795d594fSAndroid Build Coastguard Worker         /* wait for children to complete */
91*795d594fSAndroid Build Coastguard Worker         try {
92*795d594fSAndroid Build Coastguard Worker             fieldThread.join();
93*795d594fSAndroid Build Coastguard Worker             methodThread.join();
94*795d594fSAndroid Build Coastguard Worker         } catch (InterruptedException ie) {
95*795d594fSAndroid Build Coastguard Worker             System.out.println(ie);
96*795d594fSAndroid Build Coastguard Worker         }
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker         /* print all values */
99*795d594fSAndroid Build Coastguard Worker         System.out.println("Fields (main thread): " +
100*795d594fSAndroid Build Coastguard Worker             SlowInit.FIELD0.getValue() + SlowInit.FIELD1.getValue() +
101*795d594fSAndroid Build Coastguard Worker             SlowInit.FIELD2.getValue() + SlowInit.FIELD3.getValue());
102*795d594fSAndroid Build Coastguard Worker     }
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker     static class FieldThread extends Thread {
run()105*795d594fSAndroid Build Coastguard Worker         public void run() {
106*795d594fSAndroid Build Coastguard Worker             /* allow SlowInit's <clinit> to start */
107*795d594fSAndroid Build Coastguard Worker             Main.sleep(5000);
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker             /* collect fields; should delay until class init completes */
110*795d594fSAndroid Build Coastguard Worker             int field0, field1, field2, field3;
111*795d594fSAndroid Build Coastguard Worker             field0 = SlowInit.FIELD0.getValue();
112*795d594fSAndroid Build Coastguard Worker             field1 = SlowInit.FIELD1.getValue();
113*795d594fSAndroid Build Coastguard Worker             field2 = SlowInit.FIELD2.getValue();
114*795d594fSAndroid Build Coastguard Worker             field3 = SlowInit.FIELD3.getValue();
115*795d594fSAndroid Build Coastguard Worker 
116*795d594fSAndroid Build Coastguard Worker             /* let MethodThread print first */
117*795d594fSAndroid Build Coastguard Worker             Main.sleep(5000);
118*795d594fSAndroid Build Coastguard Worker             System.out.println("Fields (child thread): " +
119*795d594fSAndroid Build Coastguard Worker                 field0 + field1 + field2 + field3);
120*795d594fSAndroid Build Coastguard Worker         }
121*795d594fSAndroid Build Coastguard Worker     }
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker     static class MethodThread extends Thread {
run()124*795d594fSAndroid Build Coastguard Worker         public void run() {
125*795d594fSAndroid Build Coastguard Worker             /* allow SlowInit's <clinit> to start */
126*795d594fSAndroid Build Coastguard Worker             Main.sleep(5000);
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker             /* use a method that shouldn't be accessible yet */
129*795d594fSAndroid Build Coastguard Worker             SlowInit.printMsg("MethodThread message");
130*795d594fSAndroid Build Coastguard Worker         }
131*795d594fSAndroid Build Coastguard Worker     }
132*795d594fSAndroid Build Coastguard Worker 
checkStaticMethodInvokeAfterFailedClinit()133*795d594fSAndroid Build Coastguard Worker     static void checkStaticMethodInvokeAfterFailedClinit() {
134*795d594fSAndroid Build Coastguard Worker         System.out.println("checkStaticMethodInvokeAfterFailedClinit START");
135*795d594fSAndroid Build Coastguard Worker 
136*795d594fSAndroid Build Coastguard Worker         // Call static method to cause implicit clinit.
137*795d594fSAndroid Build Coastguard Worker         try {
138*795d594fSAndroid Build Coastguard Worker             ClassWithThrowingClinit.staticMethod();
139*795d594fSAndroid Build Coastguard Worker             System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED"
140*795d594fSAndroid Build Coastguard Worker                                + " due to missing ExceptionInInitializerError");
141*795d594fSAndroid Build Coastguard Worker         } catch (ExceptionInInitializerError expected) {
142*795d594fSAndroid Build Coastguard Worker         }
143*795d594fSAndroid Build Coastguard Worker 
144*795d594fSAndroid Build Coastguard Worker         // Call again to make sure we still get the expected error.
145*795d594fSAndroid Build Coastguard Worker         try {
146*795d594fSAndroid Build Coastguard Worker             ClassWithThrowingClinit.staticMethod();
147*795d594fSAndroid Build Coastguard Worker             System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED"
148*795d594fSAndroid Build Coastguard Worker                                + " due to missing NoClassDefFoundError");
149*795d594fSAndroid Build Coastguard Worker         } catch (NoClassDefFoundError expected) {
150*795d594fSAndroid Build Coastguard Worker         }
151*795d594fSAndroid Build Coastguard Worker         System.out.println("checkStaticMethodInvokeAfterFailedClinit PASSED");
152*795d594fSAndroid Build Coastguard Worker     }
153*795d594fSAndroid Build Coastguard Worker 
154*795d594fSAndroid Build Coastguard Worker     static class ClassWithThrowingClinit {
155*795d594fSAndroid Build Coastguard Worker         static {
throwDuringClinit()156*795d594fSAndroid Build Coastguard Worker             throwDuringClinit();
157*795d594fSAndroid Build Coastguard Worker         }
staticMethod()158*795d594fSAndroid Build Coastguard Worker         static void staticMethod() {
159*795d594fSAndroid Build Coastguard Worker         }
160*795d594fSAndroid Build Coastguard Worker     }
161*795d594fSAndroid Build Coastguard Worker }
162