Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2008 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 import other.PublicClass;
     18 import java.lang.reflect.Field;
     19 import java.lang.reflect.InvocationTargetException;
     20 import java.lang.reflect.Method;
     21 
     22 /*
     23  * Test field access through reflection.
     24  */
     25 public class Main {
     26   public static void main(String[] args) {
     27     SubClass.main(null);
     28 
     29     try {
     30       GetNonexistent.main(null);
     31       System.err.println("Not expected to succeed");
     32     } catch (VerifyError fe) {
     33       // dalvik
     34       System.out.println("Got expected failure");
     35     } catch (NoSuchFieldError nsfe) {
     36       // reference
     37       System.out.println("Got expected failure");
     38     }
     39 
     40     try {
     41       Class<?> c = Class.forName("SubClassUsingInaccessibleField");
     42       Object o = c.newInstance();
     43       c.getMethod("test").invoke(o, null);
     44     } catch (InvocationTargetException ite) {
     45       if (ite.getCause() instanceof IllegalAccessError) {
     46         System.out.println("Got expected failure");
     47       } else {
     48         System.out.println("Got unexpected failure " + ite.getCause());
     49       }
     50     } catch (Exception e) {
     51       System.out.println("Got unexpected failure " + e);
     52     }
     53   }
     54 
     55   /*
     56    * Get the field specified by "field" from "obj".
     57    *
     58    * "type" determines which "get" call is made, e.g. 'B' turns into
     59    * field.getByte().
     60    *
     61    * The "expectedException" must match the class of the exception thrown,
     62    * or be null if no exception was expected.
     63    *
     64    * On success, the boxed value retrieved is returned.
     65    */
     66   public Object getValue(Field field, Object obj, char type,
     67       Class<?> expectedException) {
     68     Object result = null;
     69     try {
     70       switch (type) {
     71         case 'Z':
     72           result = field.getBoolean(obj);
     73           break;
     74         case 'B':
     75           result = field.getByte(obj);
     76           break;
     77         case 'S':
     78           result = field.getShort(obj);
     79           break;
     80         case 'C':
     81           result = field.getChar(obj);
     82           break;
     83         case 'I':
     84           result = field.getInt(obj);
     85           break;
     86         case 'J':
     87           result = field.getLong(obj);
     88           break;
     89         case 'F':
     90           result = field.getFloat(obj);
     91           break;
     92         case 'D':
     93           result = field.getDouble(obj);
     94           break;
     95         case 'L':
     96           result = field.get(obj);
     97           break;
     98         default:
     99           throw new RuntimeException("bad type '" + type + "'");
    100       }
    101 
    102       /* success; expected? */
    103       if (expectedException != null) {
    104         System.err.println("ERROR: call succeeded for field " + field +
    105             " with a read of type '" + type +
    106             "', was expecting " + expectedException);
    107         Thread.dumpStack();
    108       }
    109     } catch (Exception ex) {
    110       if (expectedException == null) {
    111         System.err.println("ERROR: call failed unexpectedly: "
    112             + ex.getClass());
    113         ex.printStackTrace();
    114       } else {
    115         if (!expectedException.equals(ex.getClass())) {
    116           System.err.println("ERROR: incorrect exception: wanted "
    117               + expectedException.getName() + ", got "
    118               + ex.getClass());
    119           ex.printStackTrace();
    120         }
    121       }
    122     }
    123 
    124     return result;
    125   }
    126 }
    127 
    128 /*
    129  * Local class with some fields.
    130  */
    131 class SamePackage {
    132   public boolean samePackagePublicBooleanInstanceField = true;
    133   public byte samePackagePublicByteInstanceField = 2;
    134   public char samePackagePublicCharInstanceField = 3;
    135   public short samePackagePublicShortInstanceField = 4;
    136   public int samePackagePublicIntInstanceField = 5;
    137   public long samePackagePublicLongInstanceField = 6;
    138   public float samePackagePublicFloatInstanceField = 7.0f;
    139   public double samePackagePublicDoubleInstanceField = 8.0;
    140   public Object samePackagePublicObjectInstanceField = "9";
    141 
    142   protected boolean samePackageProtectedBooleanInstanceField = true;
    143   protected byte samePackageProtectedByteInstanceField = 10;
    144   protected char samePackageProtectedCharInstanceField = 11;
    145   protected short samePackageProtectedShortInstanceField = 12;
    146   protected int samePackageProtectedIntInstanceField = 13;
    147   protected long samePackageProtectedLongInstanceField = 14;
    148   protected float samePackageProtectedFloatInstanceField = 15.0f;
    149   protected double samePackageProtectedDoubleInstanceField = 16.0;
    150   protected Object samePackageProtectedObjectInstanceField = "17";
    151 
    152   private boolean samePackagePrivateBooleanInstanceField = true;
    153   private byte samePackagePrivateByteInstanceField = 18;
    154   private char samePackagePrivateCharInstanceField = 19;
    155   private short samePackagePrivateShortInstanceField = 20;
    156   private int samePackagePrivateIntInstanceField = 21;
    157   private long samePackagePrivateLongInstanceField = 22;
    158   private float samePackagePrivateFloatInstanceField = 23.0f;
    159   private double samePackagePrivateDoubleInstanceField = 24.0;
    160   private Object samePackagePrivateObjectInstanceField = "25";
    161 
    162   /* package */ boolean samePackagePackageBooleanInstanceField = true;
    163   /* package */ byte samePackagePackageByteInstanceField = 26;
    164   /* package */ char samePackagePackageCharInstanceField = 27;
    165   /* package */ short samePackagePackageShortInstanceField = 28;
    166   /* package */ int samePackagePackageIntInstanceField = 29;
    167   /* package */ long samePackagePackageLongInstanceField = 30;
    168   /* package */ float samePackagePackageFloatInstanceField = 31.0f;
    169   /* package */ double samePackagePackageDoubleInstanceField = 32.0;
    170   /* package */ Object samePackagePackageObjectInstanceField = "33";
    171 
    172   public static boolean samePackagePublicBooleanStaticField = true;
    173   public static byte samePackagePublicByteStaticField = 34;
    174   public static char samePackagePublicCharStaticField = 35;
    175   public static short samePackagePublicShortStaticField = 36;
    176   public static int samePackagePublicIntStaticField = 37;
    177   public static long samePackagePublicLongStaticField = 38;
    178   public static float samePackagePublicFloatStaticField = 39.0f;
    179   public static double samePackagePublicDoubleStaticField = 40.0;
    180   public static Object samePackagePublicObjectStaticField = "41";
    181 
    182   protected static boolean samePackageProtectedBooleanStaticField = true;
    183   protected static byte samePackageProtectedByteStaticField = 42;
    184   protected static char samePackageProtectedCharStaticField = 43;
    185   protected static short samePackageProtectedShortStaticField = 44;
    186   protected static int samePackageProtectedIntStaticField = 45;
    187   protected static long samePackageProtectedLongStaticField = 46;
    188   protected static float samePackageProtectedFloatStaticField = 47.0f;
    189   protected static double samePackageProtectedDoubleStaticField = 48.0;
    190   protected static Object samePackageProtectedObjectStaticField = "49";
    191 
    192   private static boolean samePackagePrivateBooleanStaticField = true;
    193   private static byte samePackagePrivateByteStaticField = 50;
    194   private static char samePackagePrivateCharStaticField = 51;
    195   private static short samePackagePrivateShortStaticField = 52;
    196   private static int samePackagePrivateIntStaticField = 53;
    197   private static long samePackagePrivateLongStaticField = 54;
    198   private static float samePackagePrivateFloatStaticField = 55.0f;
    199   private static double samePackagePrivateDoubleStaticField = 56.0;
    200   private static Object samePackagePrivateObjectStaticField = "57";
    201 
    202   /* package */ static boolean samePackagePackageBooleanStaticField = true;
    203   /* package */ static byte samePackagePackageByteStaticField = 58;
    204   /* package */ static char samePackagePackageCharStaticField = 59;
    205   /* package */ static short samePackagePackageShortStaticField = 60;
    206   /* package */ static int samePackagePackageIntStaticField = 61;
    207   /* package */ static long samePackagePackageLongStaticField = 62;
    208   /* package */ static float samePackagePackageFloatStaticField = 63.0f;
    209   /* package */ static double samePackagePackageDoubleStaticField = 64.0;
    210   /* package */ static Object samePackagePackageObjectStaticField = "65";
    211 
    212   public void samePublicMethod() { }
    213   protected void sameProtectedMethod() { }
    214   private void samePrivateMethod() { }
    215   /* package */ void samePackageMethod() { }
    216 }
    217 
    218 /*
    219  * This is a sub-class of other.PublicClass, which should be allowed to access
    220  * the various protected fields declared by other.PublicClass and its parent
    221  * other.ProtectedClass.
    222  */
    223 class SubClass extends PublicClass {
    224   /*
    225    * Perform the various tests.
    226    *
    227    * localInst.getValue() is performed using an instance of Main as the
    228    * source of the reflection call.  otherInst.getValue() uses a subclass
    229    * of OtherPackage as the source.
    230    */
    231   public static void main(String[] args) {
    232     SubClass subOther = new SubClass();
    233     subOther.doDirectTests();
    234     subOther.doReflectionTests();
    235   }
    236 
    237   private static void check(boolean b) {
    238     if (!b) {
    239       throw new Error("Test failed");
    240     }
    241   }
    242 
    243   public void doDirectTests() {
    244     check(otherProtectedClassPublicBooleanInstanceField == true);
    245     check(otherProtectedClassPublicByteInstanceField == 2);
    246     check(otherProtectedClassPublicCharInstanceField == 3);
    247     check(otherProtectedClassPublicShortInstanceField == 4);
    248     check(otherProtectedClassPublicIntInstanceField == 5);
    249     check(otherProtectedClassPublicLongInstanceField == 6);
    250     check(otherProtectedClassPublicFloatInstanceField == 7.0f);
    251     check(otherProtectedClassPublicDoubleInstanceField == 8.0);
    252     check(otherProtectedClassPublicObjectInstanceField == "9");
    253 
    254     check(otherProtectedClassProtectedBooleanInstanceField == true);
    255     check(otherProtectedClassProtectedByteInstanceField == 10);
    256     check(otherProtectedClassProtectedCharInstanceField == 11);
    257     check(otherProtectedClassProtectedShortInstanceField == 12);
    258     check(otherProtectedClassProtectedIntInstanceField == 13);
    259     check(otherProtectedClassProtectedLongInstanceField == 14);
    260     check(otherProtectedClassProtectedFloatInstanceField == 15.0f);
    261     check(otherProtectedClassProtectedDoubleInstanceField == 16.0);
    262     check(otherProtectedClassProtectedObjectInstanceField == "17");
    263 
    264     // check(otherProtectedClassPrivateBooleanInstanceField == true);
    265     // check(otherProtectedClassPrivateByteInstanceField == 18);
    266     // check(otherProtectedClassPrivateCharInstanceField == 19);
    267     // check(otherProtectedClassPrivateShortInstanceField == 20);
    268     // check(otherProtectedClassPrivateIntInstanceField == 21);
    269     // check(otherProtectedClassPrivateLongInstanceField == 22);
    270     // check(otherProtectedClassPrivateFloatInstanceField == 23.0f);
    271     // check(otherProtectedClassPrivateDoubleInstanceField == 24.0);
    272     // check(otherProtectedClassPrivateObjectInstanceField == "25");
    273 
    274     // check(otherProtectedClassPackageBooleanInstanceField == true);
    275     // check(otherProtectedClassPackageByteInstanceField == 26);
    276     // check(otherProtectedClassPackageCharInstanceField == 27);
    277     // check(otherProtectedClassPackageShortInstanceField == 28);
    278     // check(otherProtectedClassPackageIntInstanceField == 29);
    279     // check(otherProtectedClassPackageLongInstanceField == 30);
    280     // check(otherProtectedClassPackageFloatInstanceField == 31.0f);
    281     // check(otherProtectedClassPackageDoubleInstanceField == 32.0);
    282     // check(otherProtectedClassPackageObjectInstanceField == "33");
    283 
    284     check(otherProtectedClassPublicBooleanStaticField == true);
    285     check(otherProtectedClassPublicByteStaticField == 34);
    286     check(otherProtectedClassPublicCharStaticField == 35);
    287     check(otherProtectedClassPublicShortStaticField == 36);
    288     check(otherProtectedClassPublicIntStaticField == 37);
    289     check(otherProtectedClassPublicLongStaticField == 38);
    290     check(otherProtectedClassPublicFloatStaticField == 39.0f);
    291     check(otherProtectedClassPublicDoubleStaticField == 40.0);
    292     check(otherProtectedClassPublicObjectStaticField == "41");
    293 
    294     check(otherProtectedClassProtectedBooleanStaticField == true);
    295     check(otherProtectedClassProtectedByteStaticField == 42);
    296     check(otherProtectedClassProtectedCharStaticField == 43);
    297     check(otherProtectedClassProtectedShortStaticField == 44);
    298     check(otherProtectedClassProtectedIntStaticField == 45);
    299     check(otherProtectedClassProtectedLongStaticField == 46);
    300     check(otherProtectedClassProtectedFloatStaticField == 47.0f);
    301     check(otherProtectedClassProtectedDoubleStaticField == 48.0);
    302     check(otherProtectedClassProtectedObjectStaticField == "49");
    303 
    304     // check(otherProtectedClassPrivateBooleanStaticField == true);
    305     // check(otherProtectedClassPrivateByteStaticField == 50);
    306     // check(otherProtectedClassPrivateCharStaticField == 51);
    307     // check(otherProtectedClassPrivateShortStaticField == 52);
    308     // check(otherProtectedClassPrivateIntStaticField == 53);
    309     // check(otherProtectedClassPrivateLongStaticField == 54);
    310     // check(otherProtectedClassPrivateFloatStaticField == 55.0f);
    311     // check(otherProtectedClassPrivateDoubleStaticField == 56.0);
    312     // check(otherProtectedClassPrivateObjectStaticField == "57");
    313 
    314     // check(otherProtectedClassPackageBooleanStaticField == true);
    315     // check(otherProtectedClassPackageByteStaticField == 58);
    316     // check(otherProtectedClassPackageCharStaticField == 59);
    317     // check(otherProtectedClassPackageShortStaticField == 60);
    318     // check(otherProtectedClassPackageIntStaticField == 61);
    319     // check(otherProtectedClassPackageLongStaticField == 62);
    320     // check(otherProtectedClassPackageFloatStaticField == 63.0f);
    321     // check(otherProtectedClassPackageDoubleStaticField == 64.0);
    322     // check(otherProtectedClassPackageObjectStaticField == "65");
    323 
    324     check(otherPublicClassPublicBooleanInstanceField == true);
    325     check(otherPublicClassPublicByteInstanceField == -2);
    326     check(otherPublicClassPublicCharInstanceField == (char)-3);
    327     check(otherPublicClassPublicShortInstanceField == -4);
    328     check(otherPublicClassPublicIntInstanceField == -5);
    329     check(otherPublicClassPublicLongInstanceField == -6);
    330     check(otherPublicClassPublicFloatInstanceField == -7.0f);
    331     check(otherPublicClassPublicDoubleInstanceField == -8.0);
    332     check(otherPublicClassPublicObjectInstanceField == "-9");
    333 
    334     check(otherPublicClassProtectedBooleanInstanceField == true);
    335     check(otherPublicClassProtectedByteInstanceField == -10);
    336     check(otherPublicClassProtectedCharInstanceField == (char)-11);
    337     check(otherPublicClassProtectedShortInstanceField == -12);
    338     check(otherPublicClassProtectedIntInstanceField == -13);
    339     check(otherPublicClassProtectedLongInstanceField == -14);
    340     check(otherPublicClassProtectedFloatInstanceField == -15.0f);
    341     check(otherPublicClassProtectedDoubleInstanceField == -16.0);
    342     check(otherPublicClassProtectedObjectInstanceField == "-17");
    343 
    344     // check(otherPublicClassPrivateBooleanInstanceField == true);
    345     // check(otherPublicClassPrivateByteInstanceField == -18);
    346     // check(otherPublicClassPrivateCharInstanceField == (char)-19);
    347     // check(otherPublicClassPrivateShortInstanceField == -20);
    348     // check(otherPublicClassPrivateIntInstanceField == -21);
    349     // check(otherPublicClassPrivateLongInstanceField == -22);
    350     // check(otherPublicClassPrivateFloatInstanceField == -23.0f);
    351     // check(otherPublicClassPrivateDoubleInstanceField == -24.0);
    352     // check(otherPublicClassPrivateObjectInstanceField == "-25");
    353 
    354     // check(otherPublicClassPackageBooleanInstanceField == true);
    355     // check(otherPublicClassPackageByteInstanceField == -26);
    356     // check(otherPublicClassPackageCharInstanceField == (char)-27);
    357     // check(otherPublicClassPackageShortInstanceField == -28);
    358     // check(otherPublicClassPackageIntInstanceField == -29);
    359     // check(otherPublicClassPackageLongInstanceField == -30);
    360     // check(otherPublicClassPackageFloatInstanceField == -31.0f);
    361     // check(otherPublicClassPackageDoubleInstanceField == -32.0);
    362     // check(otherPublicClassPackageObjectInstanceField == "-33");
    363 
    364     check(otherPublicClassPublicBooleanStaticField == true);
    365     check(otherPublicClassPublicByteStaticField == -34);
    366     check(otherPublicClassPublicCharStaticField == (char)-35);
    367     check(otherPublicClassPublicShortStaticField == -36);
    368     check(otherPublicClassPublicIntStaticField == -37);
    369     check(otherPublicClassPublicLongStaticField == -38);
    370     check(otherPublicClassPublicFloatStaticField == -39.0f);
    371     check(otherPublicClassPublicDoubleStaticField == -40.0);
    372     check(otherPublicClassPublicObjectStaticField == "-41");
    373 
    374     check(otherPublicClassProtectedBooleanStaticField == true);
    375     check(otherPublicClassProtectedByteStaticField == -42);
    376     check(otherPublicClassProtectedCharStaticField == (char)-43);
    377     check(otherPublicClassProtectedShortStaticField == -44);
    378     check(otherPublicClassProtectedIntStaticField == -45);
    379     check(otherPublicClassProtectedLongStaticField == -46);
    380     check(otherPublicClassProtectedFloatStaticField == -47.0f);
    381     check(otherPublicClassProtectedDoubleStaticField == -48.0);
    382     check(otherPublicClassProtectedObjectStaticField == "-49");
    383 
    384     // check(otherPublicClassPrivateBooleanStaticField == true);
    385     // check(otherPublicClassPrivateByteStaticField == -50);
    386     // check(otherPublicClassPrivateCharStaticField == (char)-51);
    387     // check(otherPublicClassPrivateShortStaticField == -52);
    388     // check(otherPublicClassPrivateIntStaticField == -53);
    389     // check(otherPublicClassPrivateLongStaticField == -54);
    390     // check(otherPublicClassPrivateFloatStaticField == -55.0f);
    391     // check(otherPublicClassPrivateDoubleStaticField == -56.0);
    392     // check(otherPublicClassPrivateObjectStaticField == "-57");
    393 
    394     // check(otherPublicClassPackageBooleanStaticField == true);
    395     // check(otherPublicClassPackageByteStaticField == -58);
    396     // check(otherPublicClassPackageCharStaticField == (char)-59);
    397     // check(otherPublicClassPackageShortStaticField == -60);
    398     // check(otherPublicClassPackageIntStaticField == -61);
    399     // check(otherPublicClassPackageLongStaticField == -62);
    400     // check(otherPublicClassPackageFloatStaticField == -63.0f);
    401     // check(otherPublicClassPackageDoubleStaticField == -64.0);
    402     // check(otherPublicClassPackageObjectStaticField == "-65");
    403 
    404     SamePackage s = new SamePackage();
    405     check(s.samePackagePublicBooleanInstanceField == true);
    406     check(s.samePackagePublicByteInstanceField == 2);
    407     check(s.samePackagePublicCharInstanceField == 3);
    408     check(s.samePackagePublicShortInstanceField == 4);
    409     check(s.samePackagePublicIntInstanceField == 5);
    410     check(s.samePackagePublicLongInstanceField == 6);
    411     check(s.samePackagePublicFloatInstanceField == 7.0f);
    412     check(s.samePackagePublicDoubleInstanceField == 8.0);
    413     check(s.samePackagePublicObjectInstanceField == "9");
    414 
    415     check(s.samePackageProtectedBooleanInstanceField == true);
    416     check(s.samePackageProtectedByteInstanceField == 10);
    417     check(s.samePackageProtectedCharInstanceField == 11);
    418     check(s.samePackageProtectedShortInstanceField == 12);
    419     check(s.samePackageProtectedIntInstanceField == 13);
    420     check(s.samePackageProtectedLongInstanceField == 14);
    421     check(s.samePackageProtectedFloatInstanceField == 15.0f);
    422     check(s.samePackageProtectedDoubleInstanceField == 16.0);
    423     check(s.samePackageProtectedObjectInstanceField == "17");
    424 
    425     // check(s.samePackagePrivateBooleanInstanceField == true);
    426     // check(s.samePackagePrivateByteInstanceField == 18);
    427     // check(s.samePackagePrivateCharInstanceField == 19);
    428     // check(s.samePackagePrivateShortInstanceField == 20);
    429     // check(s.samePackagePrivateIntInstanceField == 21);
    430     // check(s.samePackagePrivateLongInstanceField == 22);
    431     // check(s.samePackagePrivateFloatInstanceField == 23.0f);
    432     // check(s.samePackagePrivateDoubleInstanceField == 24.0);
    433     // check(s.samePackagePrivateObjectInstanceField == "25");
    434 
    435     check(s.samePackagePackageBooleanInstanceField == true);
    436     check(s.samePackagePackageByteInstanceField == 26);
    437     check(s.samePackagePackageCharInstanceField == 27);
    438     check(s.samePackagePackageShortInstanceField == 28);
    439     check(s.samePackagePackageIntInstanceField == 29);
    440     check(s.samePackagePackageLongInstanceField == 30);
    441     check(s.samePackagePackageFloatInstanceField == 31.0f);
    442     check(s.samePackagePackageDoubleInstanceField == 32.0);
    443     check(s.samePackagePackageObjectInstanceField == "33");
    444 
    445     check(SamePackage.samePackagePublicBooleanStaticField == true);
    446     check(SamePackage.samePackagePublicByteStaticField == 34);
    447     check(SamePackage.samePackagePublicCharStaticField == 35);
    448     check(SamePackage.samePackagePublicShortStaticField == 36);
    449     check(SamePackage.samePackagePublicIntStaticField == 37);
    450     check(SamePackage.samePackagePublicLongStaticField == 38);
    451     check(SamePackage.samePackagePublicFloatStaticField == 39.0f);
    452     check(SamePackage.samePackagePublicDoubleStaticField == 40.0);
    453     check(SamePackage.samePackagePublicObjectStaticField == "41");
    454 
    455     check(SamePackage.samePackageProtectedBooleanStaticField == true);
    456     check(SamePackage.samePackageProtectedByteStaticField == 42);
    457     check(SamePackage.samePackageProtectedCharStaticField == 43);
    458     check(SamePackage.samePackageProtectedShortStaticField == 44);
    459     check(SamePackage.samePackageProtectedIntStaticField == 45);
    460     check(SamePackage.samePackageProtectedLongStaticField == 46);
    461     check(SamePackage.samePackageProtectedFloatStaticField == 47.0f);
    462     check(SamePackage.samePackageProtectedDoubleStaticField == 48.0);
    463     check(SamePackage.samePackageProtectedObjectStaticField == "49");
    464 
    465     // check(SamePackage.samePackagePrivateBooleanStaticField == true);
    466     // check(SamePackage.samePackagePrivateByteStaticField == 50);
    467     // check(SamePackage.samePackagePrivateCharStaticField == 51);
    468     // check(SamePackage.samePackagePrivateShortStaticField == 52);
    469     // check(SamePackage.samePackagePrivateIntStaticField == 53);
    470     // check(SamePackage.samePackagePrivateLongStaticField == 54);
    471     // check(SamePackage.samePackagePrivateFloatStaticField == 55.0f);
    472     // check(SamePackage.samePackagePrivateDoubleStaticField == 56.0);
    473     // check(SamePackage.samePackagePrivateObjectStaticField == "57");
    474 
    475     check(SamePackage.samePackagePackageBooleanStaticField == true);
    476     check(SamePackage.samePackagePackageByteStaticField == 58);
    477     check(SamePackage.samePackagePackageCharStaticField == 59);
    478     check(SamePackage.samePackagePackageShortStaticField == 60);
    479     check(SamePackage.samePackagePackageIntStaticField == 61);
    480     check(SamePackage.samePackagePackageLongStaticField == 62);
    481     check(SamePackage.samePackagePackageFloatStaticField == 63.0f);
    482     check(SamePackage.samePackagePackageDoubleStaticField == 64.0);
    483     check(SamePackage.samePackagePackageObjectStaticField == "65");
    484   }
    485 
    486   private static boolean compatibleTypes(char srcType, char dstType) {
    487     switch (dstType) {
    488       case 'Z':
    489       case 'C':
    490       case 'B':
    491         return srcType == dstType;
    492       case 'S':
    493         return srcType == 'B' || srcType == 'S';
    494       case 'I':
    495         return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I';
    496       case 'J':
    497         return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' ||
    498         srcType == 'J';
    499       case 'F':
    500         return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' ||
    501         srcType == 'J' || srcType == 'F';
    502       case 'D':
    503         return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' ||
    504         srcType == 'J' || srcType == 'F' || srcType == 'D';
    505       case 'L':
    506         return true;
    507       default:
    508         throw new Error("Unexpected type char " + dstType);
    509     }
    510   }
    511 
    512   public void doReflectionTests() {
    513     String typeChars = "ZBCSIJFDL";
    514     String fieldNameForTypeChar[] = {
    515         "Boolean",
    516         "Byte",
    517         "Char",
    518         "Short",
    519         "Int",
    520         "Long",
    521         "Float",
    522         "Double",
    523         "Object"
    524     };
    525 
    526     Main localInst = new Main();
    527     SamePackage samePkgInst = new SamePackage();
    528     PublicClass otherPkgInst = new PublicClass();
    529     Object plainObj = new Object();
    530 
    531     for (int round = 0; round < 3; round++) {
    532       Object validInst;
    533       Field[] fields;
    534       Method[] methods;
    535       boolean same_package = false;
    536       boolean protected_class = false;
    537       switch (round) {
    538         case 0:
    539           validInst = new SamePackage();
    540           fields = SamePackage.class.getDeclaredFields();
    541           check(fields.length == 72);
    542           methods = SamePackage.class.getDeclaredMethods();
    543           check(methods.length == 4);
    544           same_package = true;
    545           break;
    546         case 1:
    547           validInst = new PublicClass();
    548           fields = PublicClass.class.getDeclaredFields();
    549           check(fields.length == 72);
    550           methods = PublicClass.class.getDeclaredMethods();
    551           check(methods.length == 4);
    552           break;
    553         default:
    554           validInst = new PublicClass();
    555           fields = PublicClass.class.getSuperclass().getDeclaredFields();
    556           check(fields.length == 72);
    557           methods = PublicClass.class.getSuperclass().getDeclaredMethods();
    558           check(methods.length == 4);
    559           protected_class = true;
    560           break;
    561       }
    562       for (Field f : fields) {
    563         char typeChar = '?';
    564         for (int i = 0; i < fieldNameForTypeChar.length; i++) {
    565           if (f.getName().contains(fieldNameForTypeChar[i])) {
    566             typeChar = typeChars.charAt(i);
    567             break;
    568           }
    569         }
    570         // Check access or lack of to field.
    571         Class<?> subClassAccessExceptionClass = null;
    572         if ((f.getName().contains("Private") ||
    573             (!same_package && f.getName().contains("Package")) ||
    574             (!same_package && f.getName().contains("Protected"))) &&
    575             !(protected_class && f.getName().contains("Public"))) {
    576           subClassAccessExceptionClass = IllegalAccessException.class;
    577         }
    578         Class<?> mainClassAccessExceptionClass = null;
    579         if ((f.getName().contains("Private") ||
    580             (!same_package && f.getName().contains("Package")) ||
    581             (!same_package && f.getName().contains("Protected"))) &&
    582             !(protected_class && f.getName().contains("Public"))) {
    583           mainClassAccessExceptionClass = IllegalAccessException.class;
    584         }
    585 
    586         this.getValue(f, validInst, typeChar, subClassAccessExceptionClass);
    587         localInst.getValue(f, validInst, typeChar, mainClassAccessExceptionClass);
    588 
    589         // Check things that can get beyond the IllegalAccessException.
    590         if (subClassAccessExceptionClass == null) {
    591           // Check NPE.
    592           Class<?> npeClass = null;
    593           if (!f.getName().contains("Static")) {
    594             npeClass = NullPointerException.class;
    595           }
    596 
    597           this.getValue(f, null, typeChar, npeClass);
    598           if (mainClassAccessExceptionClass == null) {
    599             localInst.getValue(f, null, typeChar, npeClass);
    600           }
    601 
    602           // Check access of wrong field type for valid instance.
    603           for (int i = 0; i < typeChars.length(); i++) {
    604             char otherChar = typeChars.charAt(i);
    605             Class<?> illArgClass = compatibleTypes(typeChar, otherChar) ?
    606                 null : IllegalArgumentException.class;
    607             this.getValue(f, validInst, otherChar, illArgClass);
    608             if (mainClassAccessExceptionClass == null) {
    609               localInst.getValue(f, validInst, otherChar, illArgClass);
    610             }
    611           }
    612 
    613           if (!f.getName().contains("Static")) {
    614             // Wrong object.
    615             this.getValue(f, plainObj, typeChar, IllegalArgumentException.class);
    616             if (mainClassAccessExceptionClass == null) {
    617               localInst.getValue(f, plainObj, typeChar, IllegalArgumentException.class);
    618             }
    619           }
    620         }
    621       }
    622 
    623       for (Method m : methods) {
    624         Class<?> subClassAccessExceptionClass = null;
    625         if (m.getName().contains("Private") ||
    626             (!same_package && m.getName().contains("Package")) ||
    627             (!same_package && m.getName().contains("Protected"))) {
    628           subClassAccessExceptionClass = IllegalAccessException.class;
    629         }
    630         this.invoke(m, validInst, subClassAccessExceptionClass);
    631       }
    632     }
    633     System.out.println("good");
    634   }
    635 
    636   /*
    637    * [this is a clone of Main.getValue() -- the class issuing the
    638    * reflection call is significant]
    639    */
    640   public Object getValue(Field field, Object obj, char type,
    641       Class<?> expectedException) {
    642     Object result = null;
    643     try {
    644       switch (type) {
    645         case 'Z':
    646           result = field.getBoolean(obj);
    647           break;
    648         case 'B':
    649           result = field.getByte(obj);
    650           break;
    651         case 'S':
    652           result = field.getShort(obj);
    653           break;
    654         case 'C':
    655           result = field.getChar(obj);
    656           break;
    657         case 'I':
    658           result = field.getInt(obj);
    659           break;
    660         case 'J':
    661           result = field.getLong(obj);
    662           break;
    663         case 'F':
    664           result = field.getFloat(obj);
    665           break;
    666         case 'D':
    667           result = field.getDouble(obj);
    668           break;
    669         case 'L':
    670           result = field.get(obj);
    671           break;
    672         default:
    673           throw new RuntimeException("bad type '" + type + "'");
    674       }
    675 
    676       /* success; expected? */
    677       if (expectedException != null) {
    678         System.err.println("ERROR: call succeeded for field " + field +
    679             " with a read of type '" + type +
    680             "', was expecting " + expectedException);
    681         Thread.dumpStack();
    682       }
    683     } catch (Exception ex) {
    684       if (expectedException == null) {
    685         System.err.println("ERROR: call failed unexpectedly: "
    686             + ex.getClass());
    687         ex.printStackTrace();
    688       } else {
    689         if (!expectedException.equals(ex.getClass())) {
    690           System.err.println("ERROR: incorrect exception: wanted "
    691               + expectedException.getName() + ", got "
    692               + ex.getClass());
    693           ex.printStackTrace();
    694         }
    695       }
    696     }
    697 
    698     return result;
    699   }
    700 
    701   public Object invoke(Method method, Object obj, Class<?> expectedException) {
    702     Object result = null;
    703     try {
    704       result = method.invoke(obj);
    705       /* success; expected? */
    706       if (expectedException != null) {
    707         System.err.println("ERROR: call succeeded for method " + method + "', was expecting " +
    708                            expectedException);
    709         Thread.dumpStack();
    710       }
    711     } catch (Exception ex) {
    712       if (expectedException == null) {
    713         System.err.println("ERROR: call failed unexpectedly: " + ex.getClass());
    714         ex.printStackTrace();
    715       } else {
    716         if (!expectedException.equals(ex.getClass())) {
    717           System.err.println("ERROR: incorrect exception: wanted " + expectedException.getName() +
    718                              ", got " + ex.getClass());
    719           ex.printStackTrace();
    720         }
    721       }
    722     }
    723     return result;
    724   }
    725 }
    726