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