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