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