15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Copyright (C) 2010 The Android Open Source Project
35d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Licensed under the Apache License, Version 2.0 (the "License");
55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * you may not use this file except in compliance with the License.
65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * You may obtain a copy of the License at
75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *      http://www.apache.org/licenses/LICENSE-2.0
95d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Unless required by applicable law or agreed to in writing, software
115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * distributed under the License is distributed on an "AS IS" BASIS,
125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * See the License for the specific language governing permissions and
145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * limitations under the License.
155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class Main {
18a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes    static {
1979686a02c512d9cde16a40f70df8ce4a52606754Elliott Hughes        staticMethodCalledByClinit();
20a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes    }
21a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes
2279686a02c512d9cde16a40f70df8ce4a52606754Elliott Hughes    private static void staticMethodCalledByClinit() {
2379686a02c512d9cde16a40f70df8ce4a52606754Elliott Hughes        // Test that DeliverException works when we need to unwind to a handler -- this method --
2479686a02c512d9cde16a40f70df8ce4a52606754Elliott Hughes        // that is currently a resolution stub because it's running on behalf of <clinit>.
25a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes        try {
26a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes            throwDuringClinit();
27a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes            System.err.println("didn't throw!");
28a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes        } catch (NullPointerException ex) {
29a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes            System.out.println("caught exception thrown during clinit");
30a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes        }
31a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes    }
32a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes
33a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes    private static void throwDuringClinit() {
34a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes        throw new NullPointerException();
35a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes    }
36a58ff1773332ade8b2da86cf2658bd5066fb4606Elliott Hughes
375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void main(String[] args) {
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        checkExceptions();
395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        checkTiming();
40073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        checkStaticMethodInvokeAfterFailedClinit();
415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void sleep(int msec) {
445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Thread.sleep(msec);
465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InterruptedException ie) {
475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("sleep interrupted");
485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void checkExceptions() {
525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(PartialInit.FIELD0);
545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("Construction of PartialInit succeeded unexpectedly");
555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ExceptionInInitializerError eiie) {
565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected EIIE for FIELD0");
575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(PartialInit.FIELD0);
615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("Load of FIELD0 succeeded unexpectedly");
625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (NoClassDefFoundError ncdfe) {
635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected NCDFE for FIELD0");
645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(PartialInit.FIELD1);
675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("Load of FIELD1 succeeded unexpectedly");
685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (NoClassDefFoundError ncdfe) {
695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected NCDFE for FIELD1");
705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
714f3d94b4e3b40fa7aa2bb5007fa4bb5703189b61Elliott Hughes
724f3d94b4e3b40fa7aa2bb5007fa4bb5703189b61Elliott Hughes        try {
734f3d94b4e3b40fa7aa2bb5007fa4bb5703189b61Elliott Hughes            System.out.println(Exploder.FIELD);
744f3d94b4e3b40fa7aa2bb5007fa4bb5703189b61Elliott Hughes            System.err.println("Load of FIELD succeeded unexpectedly");
754f3d94b4e3b40fa7aa2bb5007fa4bb5703189b61Elliott Hughes        } catch (AssertionError expected) {
764f3d94b4e3b40fa7aa2bb5007fa4bb5703189b61Elliott Hughes            System.out.println("Got expected '" + expected.getMessage() + "' from Exploder");
774f3d94b4e3b40fa7aa2bb5007fa4bb5703189b61Elliott Hughes        }
785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void checkTiming() {
815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        FieldThread fieldThread = new FieldThread();
825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        MethodThread methodThread = new MethodThread();
835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        fieldThread.start();
855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        methodThread.start();
865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* start class init */
885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        IntHolder zero = SlowInit.FIELD0;
895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* wait for children to complete */
915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            fieldThread.join();
935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            methodThread.join();
945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InterruptedException ie) {
955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println(ie);
965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* print all values */
995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("Fields (main thread): " +
1005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            SlowInit.FIELD0.getValue() + SlowInit.FIELD1.getValue() +
1015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            SlowInit.FIELD2.getValue() + SlowInit.FIELD3.getValue());
1025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static class FieldThread extends Thread {
1055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        public void run() {
106741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            /* allow SlowInit's <clinit> to start */
10794d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao            Main.sleep(5000);
1085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            /* collect fields; should delay until class init completes */
1105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            int field0, field1, field2, field3;
1115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            field0 = SlowInit.FIELD0.getValue();
1125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            field1 = SlowInit.FIELD1.getValue();
1135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            field2 = SlowInit.FIELD2.getValue();
1145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            field3 = SlowInit.FIELD3.getValue();
1155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            /* let MethodThread print first */
117741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            Main.sleep(5000);
1185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Fields (child thread): " +
1195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                field0 + field1 + field2 + field3);
1205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static class MethodThread extends Thread {
1245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        public void run() {
125741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            /* allow SlowInit's <clinit> to start */
12694d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao            Main.sleep(5000);
1275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            /* use a method that shouldn't be accessible yet */
1295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            SlowInit.printMsg("MethodThread message");
1305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
132073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom
133073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom    static void checkStaticMethodInvokeAfterFailedClinit() {
134073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        System.out.println("checkStaticMethodInvokeAfterFailedClinit START");
135073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom
136073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        // Call static method to cause implicit clinit.
137073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        try {
138073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom            ClassWithThrowingClinit.staticMethod();
139073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom            System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED"
140073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom                               + " due to missing ExceptionInInitializerError");
141073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        } catch (ExceptionInInitializerError expected) {
142073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        }
143073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom
144073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        // Call again to make sure we still get the expected error.
145073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        try {
146073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom            ClassWithThrowingClinit.staticMethod();
147073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom            System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED"
148073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom                               + " due to missing NoClassDefFoundError");
149073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        } catch (NoClassDefFoundError expected) {
150073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        }
151073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        System.out.println("checkStaticMethodInvokeAfterFailedClinit PASSED");
152073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom    }
153073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom
154073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom    static class ClassWithThrowingClinit {
155073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        static {
156073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom            throwDuringClinit();
157073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        }
158073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        static void staticMethod() {
159073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom        }
160073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom    }
1615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
162