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