/*
|
* Copyright (C) 2008 The Android Open Source Project
|
*
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* you may not use this file except in compliance with the License.
|
* You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
*/
|
|
import other.PublicClass;
|
import java.lang.reflect.Field;
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
|
/*
|
* Test field access through reflection.
|
*/
|
public class Main {
|
public static void main(String[] args) {
|
System.loadLibrary(args[0]);
|
|
SubClass.main(null);
|
|
try {
|
GetNonexistent.main(null);
|
System.out.println("Not expected to succeed");
|
} catch (VerifyError fe) {
|
// dalvik
|
System.out.println("Got expected failure");
|
} catch (NoSuchFieldError nsfe) {
|
// reference
|
System.out.println("Got expected failure");
|
}
|
|
try {
|
Class<?> c = Class.forName("SubClassUsingInaccessibleField");
|
Object o = c.newInstance();
|
c.getMethod("test").invoke(o, null);
|
} catch (InvocationTargetException ite) {
|
if (ite.getCause() instanceof IllegalAccessError) {
|
System.out.println("Got expected failure");
|
} else {
|
System.out.println("Got unexpected failure " + ite.getCause());
|
}
|
} catch (Exception e) {
|
System.out.println("Got unexpected failure " + e);
|
}
|
|
OOMEOnNullAccess.main(args);
|
}
|
|
/*
|
* Get the field specified by "field" from "obj".
|
*
|
* "type" determines which "get" call is made, e.g. 'B' turns into
|
* field.getByte().
|
*
|
* The "expectedException" must match the class of the exception thrown,
|
* or be null if no exception was expected.
|
*
|
* On success, the boxed value retrieved is returned.
|
*/
|
public Object getValue(Field field, Object obj, char type,
|
Class<?> expectedException) {
|
Object result = null;
|
try {
|
switch (type) {
|
case 'Z':
|
result = field.getBoolean(obj);
|
break;
|
case 'B':
|
result = field.getByte(obj);
|
break;
|
case 'S':
|
result = field.getShort(obj);
|
break;
|
case 'C':
|
result = field.getChar(obj);
|
break;
|
case 'I':
|
result = field.getInt(obj);
|
break;
|
case 'J':
|
result = field.getLong(obj);
|
break;
|
case 'F':
|
result = field.getFloat(obj);
|
break;
|
case 'D':
|
result = field.getDouble(obj);
|
break;
|
case 'L':
|
result = field.get(obj);
|
break;
|
default:
|
throw new RuntimeException("bad type '" + type + "'");
|
}
|
|
/* success; expected? */
|
if (expectedException != null) {
|
System.out.println("ERROR: call succeeded for field " + field +
|
" with a read of type '" + type +
|
"', was expecting " + expectedException);
|
Thread.dumpStack();
|
}
|
} catch (Exception ex) {
|
if (expectedException == null) {
|
System.out.println("ERROR: call failed unexpectedly: "
|
+ ex.getClass());
|
ex.printStackTrace(System.out);
|
} else {
|
if (!expectedException.equals(ex.getClass())) {
|
System.out.println("ERROR: incorrect exception: wanted "
|
+ expectedException.getName() + ", got "
|
+ ex.getClass());
|
ex.printStackTrace(System.out);
|
}
|
}
|
}
|
|
return result;
|
}
|
|
static native void startJit();
|
static native void stopJit();
|
static native void waitForCompilation();
|
}
|
|
/*
|
* Local class with some fields.
|
*/
|
class SamePackage {
|
public boolean samePackagePublicBooleanInstanceField = true;
|
public byte samePackagePublicByteInstanceField = 2;
|
public char samePackagePublicCharInstanceField = 3;
|
public short samePackagePublicShortInstanceField = 4;
|
public int samePackagePublicIntInstanceField = 5;
|
public long samePackagePublicLongInstanceField = 6;
|
public float samePackagePublicFloatInstanceField = 7.0f;
|
public double samePackagePublicDoubleInstanceField = 8.0;
|
public Object samePackagePublicObjectInstanceField = "9";
|
|
protected boolean samePackageProtectedBooleanInstanceField = true;
|
protected byte samePackageProtectedByteInstanceField = 10;
|
protected char samePackageProtectedCharInstanceField = 11;
|
protected short samePackageProtectedShortInstanceField = 12;
|
protected int samePackageProtectedIntInstanceField = 13;
|
protected long samePackageProtectedLongInstanceField = 14;
|
protected float samePackageProtectedFloatInstanceField = 15.0f;
|
protected double samePackageProtectedDoubleInstanceField = 16.0;
|
protected Object samePackageProtectedObjectInstanceField = "17";
|
|
private boolean samePackagePrivateBooleanInstanceField = true;
|
private byte samePackagePrivateByteInstanceField = 18;
|
private char samePackagePrivateCharInstanceField = 19;
|
private short samePackagePrivateShortInstanceField = 20;
|
private int samePackagePrivateIntInstanceField = 21;
|
private long samePackagePrivateLongInstanceField = 22;
|
private float samePackagePrivateFloatInstanceField = 23.0f;
|
private double samePackagePrivateDoubleInstanceField = 24.0;
|
private Object samePackagePrivateObjectInstanceField = "25";
|
|
/* package */ boolean samePackagePackageBooleanInstanceField = true;
|
/* package */ byte samePackagePackageByteInstanceField = 26;
|
/* package */ char samePackagePackageCharInstanceField = 27;
|
/* package */ short samePackagePackageShortInstanceField = 28;
|
/* package */ int samePackagePackageIntInstanceField = 29;
|
/* package */ long samePackagePackageLongInstanceField = 30;
|
/* package */ float samePackagePackageFloatInstanceField = 31.0f;
|
/* package */ double samePackagePackageDoubleInstanceField = 32.0;
|
/* package */ Object samePackagePackageObjectInstanceField = "33";
|
|
public static boolean samePackagePublicBooleanStaticField = true;
|
public static byte samePackagePublicByteStaticField = 34;
|
public static char samePackagePublicCharStaticField = 35;
|
public static short samePackagePublicShortStaticField = 36;
|
public static int samePackagePublicIntStaticField = 37;
|
public static long samePackagePublicLongStaticField = 38;
|
public static float samePackagePublicFloatStaticField = 39.0f;
|
public static double samePackagePublicDoubleStaticField = 40.0;
|
public static Object samePackagePublicObjectStaticField = "41";
|
|
protected static boolean samePackageProtectedBooleanStaticField = true;
|
protected static byte samePackageProtectedByteStaticField = 42;
|
protected static char samePackageProtectedCharStaticField = 43;
|
protected static short samePackageProtectedShortStaticField = 44;
|
protected static int samePackageProtectedIntStaticField = 45;
|
protected static long samePackageProtectedLongStaticField = 46;
|
protected static float samePackageProtectedFloatStaticField = 47.0f;
|
protected static double samePackageProtectedDoubleStaticField = 48.0;
|
protected static Object samePackageProtectedObjectStaticField = "49";
|
|
private static boolean samePackagePrivateBooleanStaticField = true;
|
private static byte samePackagePrivateByteStaticField = 50;
|
private static char samePackagePrivateCharStaticField = 51;
|
private static short samePackagePrivateShortStaticField = 52;
|
private static int samePackagePrivateIntStaticField = 53;
|
private static long samePackagePrivateLongStaticField = 54;
|
private static float samePackagePrivateFloatStaticField = 55.0f;
|
private static double samePackagePrivateDoubleStaticField = 56.0;
|
private static Object samePackagePrivateObjectStaticField = "57";
|
|
/* package */ static boolean samePackagePackageBooleanStaticField = true;
|
/* package */ static byte samePackagePackageByteStaticField = 58;
|
/* package */ static char samePackagePackageCharStaticField = 59;
|
/* package */ static short samePackagePackageShortStaticField = 60;
|
/* package */ static int samePackagePackageIntStaticField = 61;
|
/* package */ static long samePackagePackageLongStaticField = 62;
|
/* package */ static float samePackagePackageFloatStaticField = 63.0f;
|
/* package */ static double samePackagePackageDoubleStaticField = 64.0;
|
/* package */ static Object samePackagePackageObjectStaticField = "65";
|
|
public void samePublicMethod() { }
|
protected void sameProtectedMethod() { }
|
private void samePrivateMethod() { }
|
/* package */ void samePackageMethod() { }
|
}
|
|
/*
|
* This is a sub-class of other.PublicClass, which should be allowed to access
|
* the various protected fields declared by other.PublicClass and its parent
|
* other.ProtectedClass.
|
*/
|
class SubClass extends PublicClass {
|
/*
|
* Perform the various tests.
|
*
|
* localInst.getValue() is performed using an instance of Main as the
|
* source of the reflection call. otherInst.getValue() uses a subclass
|
* of OtherPackage as the source.
|
*/
|
public static void main(String[] args) {
|
SubClass subOther = new SubClass();
|
subOther.doDirectTests();
|
subOther.doReflectionTests();
|
}
|
|
private static void check(boolean b) {
|
if (!b) {
|
throw new Error("Test failed");
|
}
|
}
|
|
public void doDirectTests() {
|
check(otherProtectedClassPublicBooleanInstanceField == true);
|
check(otherProtectedClassPublicByteInstanceField == 2);
|
check(otherProtectedClassPublicCharInstanceField == 3);
|
check(otherProtectedClassPublicShortInstanceField == 4);
|
check(otherProtectedClassPublicIntInstanceField == 5);
|
check(otherProtectedClassPublicLongInstanceField == 6);
|
check(otherProtectedClassPublicFloatInstanceField == 7.0f);
|
check(otherProtectedClassPublicDoubleInstanceField == 8.0);
|
check(otherProtectedClassPublicObjectInstanceField == "9");
|
|
check(otherProtectedClassProtectedBooleanInstanceField == true);
|
check(otherProtectedClassProtectedByteInstanceField == 10);
|
check(otherProtectedClassProtectedCharInstanceField == 11);
|
check(otherProtectedClassProtectedShortInstanceField == 12);
|
check(otherProtectedClassProtectedIntInstanceField == 13);
|
check(otherProtectedClassProtectedLongInstanceField == 14);
|
check(otherProtectedClassProtectedFloatInstanceField == 15.0f);
|
check(otherProtectedClassProtectedDoubleInstanceField == 16.0);
|
check(otherProtectedClassProtectedObjectInstanceField == "17");
|
|
// check(otherProtectedClassPrivateBooleanInstanceField == true);
|
// check(otherProtectedClassPrivateByteInstanceField == 18);
|
// check(otherProtectedClassPrivateCharInstanceField == 19);
|
// check(otherProtectedClassPrivateShortInstanceField == 20);
|
// check(otherProtectedClassPrivateIntInstanceField == 21);
|
// check(otherProtectedClassPrivateLongInstanceField == 22);
|
// check(otherProtectedClassPrivateFloatInstanceField == 23.0f);
|
// check(otherProtectedClassPrivateDoubleInstanceField == 24.0);
|
// check(otherProtectedClassPrivateObjectInstanceField == "25");
|
|
// check(otherProtectedClassPackageBooleanInstanceField == true);
|
// check(otherProtectedClassPackageByteInstanceField == 26);
|
// check(otherProtectedClassPackageCharInstanceField == 27);
|
// check(otherProtectedClassPackageShortInstanceField == 28);
|
// check(otherProtectedClassPackageIntInstanceField == 29);
|
// check(otherProtectedClassPackageLongInstanceField == 30);
|
// check(otherProtectedClassPackageFloatInstanceField == 31.0f);
|
// check(otherProtectedClassPackageDoubleInstanceField == 32.0);
|
// check(otherProtectedClassPackageObjectInstanceField == "33");
|
|
check(otherProtectedClassPublicBooleanStaticField == true);
|
check(otherProtectedClassPublicByteStaticField == 34);
|
check(otherProtectedClassPublicCharStaticField == 35);
|
check(otherProtectedClassPublicShortStaticField == 36);
|
check(otherProtectedClassPublicIntStaticField == 37);
|
check(otherProtectedClassPublicLongStaticField == 38);
|
check(otherProtectedClassPublicFloatStaticField == 39.0f);
|
check(otherProtectedClassPublicDoubleStaticField == 40.0);
|
check(otherProtectedClassPublicObjectStaticField == "41");
|
|
check(otherProtectedClassProtectedBooleanStaticField == true);
|
check(otherProtectedClassProtectedByteStaticField == 42);
|
check(otherProtectedClassProtectedCharStaticField == 43);
|
check(otherProtectedClassProtectedShortStaticField == 44);
|
check(otherProtectedClassProtectedIntStaticField == 45);
|
check(otherProtectedClassProtectedLongStaticField == 46);
|
check(otherProtectedClassProtectedFloatStaticField == 47.0f);
|
check(otherProtectedClassProtectedDoubleStaticField == 48.0);
|
check(otherProtectedClassProtectedObjectStaticField == "49");
|
|
// check(otherProtectedClassPrivateBooleanStaticField == true);
|
// check(otherProtectedClassPrivateByteStaticField == 50);
|
// check(otherProtectedClassPrivateCharStaticField == 51);
|
// check(otherProtectedClassPrivateShortStaticField == 52);
|
// check(otherProtectedClassPrivateIntStaticField == 53);
|
// check(otherProtectedClassPrivateLongStaticField == 54);
|
// check(otherProtectedClassPrivateFloatStaticField == 55.0f);
|
// check(otherProtectedClassPrivateDoubleStaticField == 56.0);
|
// check(otherProtectedClassPrivateObjectStaticField == "57");
|
|
// check(otherProtectedClassPackageBooleanStaticField == true);
|
// check(otherProtectedClassPackageByteStaticField == 58);
|
// check(otherProtectedClassPackageCharStaticField == 59);
|
// check(otherProtectedClassPackageShortStaticField == 60);
|
// check(otherProtectedClassPackageIntStaticField == 61);
|
// check(otherProtectedClassPackageLongStaticField == 62);
|
// check(otherProtectedClassPackageFloatStaticField == 63.0f);
|
// check(otherProtectedClassPackageDoubleStaticField == 64.0);
|
// check(otherProtectedClassPackageObjectStaticField == "65");
|
|
check(otherPublicClassPublicBooleanInstanceField == true);
|
check(otherPublicClassPublicByteInstanceField == -2);
|
check(otherPublicClassPublicCharInstanceField == (char)-3);
|
check(otherPublicClassPublicShortInstanceField == -4);
|
check(otherPublicClassPublicIntInstanceField == -5);
|
check(otherPublicClassPublicLongInstanceField == -6);
|
check(otherPublicClassPublicFloatInstanceField == -7.0f);
|
check(otherPublicClassPublicDoubleInstanceField == -8.0);
|
check(otherPublicClassPublicObjectInstanceField == "-9");
|
|
check(otherPublicClassProtectedBooleanInstanceField == true);
|
check(otherPublicClassProtectedByteInstanceField == -10);
|
check(otherPublicClassProtectedCharInstanceField == (char)-11);
|
check(otherPublicClassProtectedShortInstanceField == -12);
|
check(otherPublicClassProtectedIntInstanceField == -13);
|
check(otherPublicClassProtectedLongInstanceField == -14);
|
check(otherPublicClassProtectedFloatInstanceField == -15.0f);
|
check(otherPublicClassProtectedDoubleInstanceField == -16.0);
|
check(otherPublicClassProtectedObjectInstanceField == "-17");
|
|
// check(otherPublicClassPrivateBooleanInstanceField == true);
|
// check(otherPublicClassPrivateByteInstanceField == -18);
|
// check(otherPublicClassPrivateCharInstanceField == (char)-19);
|
// check(otherPublicClassPrivateShortInstanceField == -20);
|
// check(otherPublicClassPrivateIntInstanceField == -21);
|
// check(otherPublicClassPrivateLongInstanceField == -22);
|
// check(otherPublicClassPrivateFloatInstanceField == -23.0f);
|
// check(otherPublicClassPrivateDoubleInstanceField == -24.0);
|
// check(otherPublicClassPrivateObjectInstanceField == "-25");
|
|
// check(otherPublicClassPackageBooleanInstanceField == true);
|
// check(otherPublicClassPackageByteInstanceField == -26);
|
// check(otherPublicClassPackageCharInstanceField == (char)-27);
|
// check(otherPublicClassPackageShortInstanceField == -28);
|
// check(otherPublicClassPackageIntInstanceField == -29);
|
// check(otherPublicClassPackageLongInstanceField == -30);
|
// check(otherPublicClassPackageFloatInstanceField == -31.0f);
|
// check(otherPublicClassPackageDoubleInstanceField == -32.0);
|
// check(otherPublicClassPackageObjectInstanceField == "-33");
|
|
check(otherPublicClassPublicBooleanStaticField == true);
|
check(otherPublicClassPublicByteStaticField == -34);
|
check(otherPublicClassPublicCharStaticField == (char)-35);
|
check(otherPublicClassPublicShortStaticField == -36);
|
check(otherPublicClassPublicIntStaticField == -37);
|
check(otherPublicClassPublicLongStaticField == -38);
|
check(otherPublicClassPublicFloatStaticField == -39.0f);
|
check(otherPublicClassPublicDoubleStaticField == -40.0);
|
check(otherPublicClassPublicObjectStaticField == "-41");
|
|
check(otherPublicClassProtectedBooleanStaticField == true);
|
check(otherPublicClassProtectedByteStaticField == -42);
|
check(otherPublicClassProtectedCharStaticField == (char)-43);
|
check(otherPublicClassProtectedShortStaticField == -44);
|
check(otherPublicClassProtectedIntStaticField == -45);
|
check(otherPublicClassProtectedLongStaticField == -46);
|
check(otherPublicClassProtectedFloatStaticField == -47.0f);
|
check(otherPublicClassProtectedDoubleStaticField == -48.0);
|
check(otherPublicClassProtectedObjectStaticField == "-49");
|
|
// check(otherPublicClassPrivateBooleanStaticField == true);
|
// check(otherPublicClassPrivateByteStaticField == -50);
|
// check(otherPublicClassPrivateCharStaticField == (char)-51);
|
// check(otherPublicClassPrivateShortStaticField == -52);
|
// check(otherPublicClassPrivateIntStaticField == -53);
|
// check(otherPublicClassPrivateLongStaticField == -54);
|
// check(otherPublicClassPrivateFloatStaticField == -55.0f);
|
// check(otherPublicClassPrivateDoubleStaticField == -56.0);
|
// check(otherPublicClassPrivateObjectStaticField == "-57");
|
|
// check(otherPublicClassPackageBooleanStaticField == true);
|
// check(otherPublicClassPackageByteStaticField == -58);
|
// check(otherPublicClassPackageCharStaticField == (char)-59);
|
// check(otherPublicClassPackageShortStaticField == -60);
|
// check(otherPublicClassPackageIntStaticField == -61);
|
// check(otherPublicClassPackageLongStaticField == -62);
|
// check(otherPublicClassPackageFloatStaticField == -63.0f);
|
// check(otherPublicClassPackageDoubleStaticField == -64.0);
|
// check(otherPublicClassPackageObjectStaticField == "-65");
|
|
SamePackage s = new SamePackage();
|
check(s.samePackagePublicBooleanInstanceField == true);
|
check(s.samePackagePublicByteInstanceField == 2);
|
check(s.samePackagePublicCharInstanceField == 3);
|
check(s.samePackagePublicShortInstanceField == 4);
|
check(s.samePackagePublicIntInstanceField == 5);
|
check(s.samePackagePublicLongInstanceField == 6);
|
check(s.samePackagePublicFloatInstanceField == 7.0f);
|
check(s.samePackagePublicDoubleInstanceField == 8.0);
|
check(s.samePackagePublicObjectInstanceField == "9");
|
|
check(s.samePackageProtectedBooleanInstanceField == true);
|
check(s.samePackageProtectedByteInstanceField == 10);
|
check(s.samePackageProtectedCharInstanceField == 11);
|
check(s.samePackageProtectedShortInstanceField == 12);
|
check(s.samePackageProtectedIntInstanceField == 13);
|
check(s.samePackageProtectedLongInstanceField == 14);
|
check(s.samePackageProtectedFloatInstanceField == 15.0f);
|
check(s.samePackageProtectedDoubleInstanceField == 16.0);
|
check(s.samePackageProtectedObjectInstanceField == "17");
|
|
// check(s.samePackagePrivateBooleanInstanceField == true);
|
// check(s.samePackagePrivateByteInstanceField == 18);
|
// check(s.samePackagePrivateCharInstanceField == 19);
|
// check(s.samePackagePrivateShortInstanceField == 20);
|
// check(s.samePackagePrivateIntInstanceField == 21);
|
// check(s.samePackagePrivateLongInstanceField == 22);
|
// check(s.samePackagePrivateFloatInstanceField == 23.0f);
|
// check(s.samePackagePrivateDoubleInstanceField == 24.0);
|
// check(s.samePackagePrivateObjectInstanceField == "25");
|
|
check(s.samePackagePackageBooleanInstanceField == true);
|
check(s.samePackagePackageByteInstanceField == 26);
|
check(s.samePackagePackageCharInstanceField == 27);
|
check(s.samePackagePackageShortInstanceField == 28);
|
check(s.samePackagePackageIntInstanceField == 29);
|
check(s.samePackagePackageLongInstanceField == 30);
|
check(s.samePackagePackageFloatInstanceField == 31.0f);
|
check(s.samePackagePackageDoubleInstanceField == 32.0);
|
check(s.samePackagePackageObjectInstanceField == "33");
|
|
check(SamePackage.samePackagePublicBooleanStaticField == true);
|
check(SamePackage.samePackagePublicByteStaticField == 34);
|
check(SamePackage.samePackagePublicCharStaticField == 35);
|
check(SamePackage.samePackagePublicShortStaticField == 36);
|
check(SamePackage.samePackagePublicIntStaticField == 37);
|
check(SamePackage.samePackagePublicLongStaticField == 38);
|
check(SamePackage.samePackagePublicFloatStaticField == 39.0f);
|
check(SamePackage.samePackagePublicDoubleStaticField == 40.0);
|
check(SamePackage.samePackagePublicObjectStaticField == "41");
|
|
check(SamePackage.samePackageProtectedBooleanStaticField == true);
|
check(SamePackage.samePackageProtectedByteStaticField == 42);
|
check(SamePackage.samePackageProtectedCharStaticField == 43);
|
check(SamePackage.samePackageProtectedShortStaticField == 44);
|
check(SamePackage.samePackageProtectedIntStaticField == 45);
|
check(SamePackage.samePackageProtectedLongStaticField == 46);
|
check(SamePackage.samePackageProtectedFloatStaticField == 47.0f);
|
check(SamePackage.samePackageProtectedDoubleStaticField == 48.0);
|
check(SamePackage.samePackageProtectedObjectStaticField == "49");
|
|
// check(SamePackage.samePackagePrivateBooleanStaticField == true);
|
// check(SamePackage.samePackagePrivateByteStaticField == 50);
|
// check(SamePackage.samePackagePrivateCharStaticField == 51);
|
// check(SamePackage.samePackagePrivateShortStaticField == 52);
|
// check(SamePackage.samePackagePrivateIntStaticField == 53);
|
// check(SamePackage.samePackagePrivateLongStaticField == 54);
|
// check(SamePackage.samePackagePrivateFloatStaticField == 55.0f);
|
// check(SamePackage.samePackagePrivateDoubleStaticField == 56.0);
|
// check(SamePackage.samePackagePrivateObjectStaticField == "57");
|
|
check(SamePackage.samePackagePackageBooleanStaticField == true);
|
check(SamePackage.samePackagePackageByteStaticField == 58);
|
check(SamePackage.samePackagePackageCharStaticField == 59);
|
check(SamePackage.samePackagePackageShortStaticField == 60);
|
check(SamePackage.samePackagePackageIntStaticField == 61);
|
check(SamePackage.samePackagePackageLongStaticField == 62);
|
check(SamePackage.samePackagePackageFloatStaticField == 63.0f);
|
check(SamePackage.samePackagePackageDoubleStaticField == 64.0);
|
check(SamePackage.samePackagePackageObjectStaticField == "65");
|
}
|
|
private static boolean compatibleTypes(char srcType, char dstType) {
|
switch (dstType) {
|
case 'Z':
|
case 'C':
|
case 'B':
|
return srcType == dstType;
|
case 'S':
|
return srcType == 'B' || srcType == 'S';
|
case 'I':
|
return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I';
|
case 'J':
|
return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' ||
|
srcType == 'J';
|
case 'F':
|
return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' ||
|
srcType == 'J' || srcType == 'F';
|
case 'D':
|
return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' ||
|
srcType == 'J' || srcType == 'F' || srcType == 'D';
|
case 'L':
|
return true;
|
default:
|
throw new Error("Unexpected type char " + dstType);
|
}
|
}
|
|
public void doReflectionTests() {
|
String typeChars = "ZBCSIJFDL";
|
String fieldNameForTypeChar[] = {
|
"Boolean",
|
"Byte",
|
"Char",
|
"Short",
|
"Int",
|
"Long",
|
"Float",
|
"Double",
|
"Object"
|
};
|
|
Main localInst = new Main();
|
SamePackage samePkgInst = new SamePackage();
|
PublicClass otherPkgInst = new PublicClass();
|
Object plainObj = new Object();
|
|
for (int round = 0; round < 3; round++) {
|
Object validInst;
|
Field[] fields;
|
Method[] methods;
|
boolean same_package = false;
|
boolean protected_class = false;
|
switch (round) {
|
case 0:
|
validInst = new SamePackage();
|
fields = SamePackage.class.getDeclaredFields();
|
check(fields.length == 72);
|
methods = SamePackage.class.getDeclaredMethods();
|
check(methods.length == 4);
|
same_package = true;
|
break;
|
case 1:
|
validInst = new PublicClass();
|
fields = PublicClass.class.getDeclaredFields();
|
check(fields.length == 72);
|
methods = PublicClass.class.getDeclaredMethods();
|
check(methods.length == 4);
|
break;
|
default:
|
validInst = new PublicClass();
|
fields = PublicClass.class.getSuperclass().getDeclaredFields();
|
check(fields.length == 72);
|
methods = PublicClass.class.getSuperclass().getDeclaredMethods();
|
check(methods.length == 4);
|
protected_class = true;
|
break;
|
}
|
for (Field f : fields) {
|
char typeChar = '?';
|
for (int i = 0; i < fieldNameForTypeChar.length; i++) {
|
if (f.getName().contains(fieldNameForTypeChar[i])) {
|
typeChar = typeChars.charAt(i);
|
break;
|
}
|
}
|
// Check access or lack of to field.
|
Class<?> subClassAccessExceptionClass = null;
|
if ((f.getName().contains("Private") ||
|
(!same_package && f.getName().contains("Package")) ||
|
(!same_package && f.getName().contains("Protected"))) &&
|
!(protected_class && f.getName().contains("Public"))) {
|
subClassAccessExceptionClass = IllegalAccessException.class;
|
}
|
Class<?> mainClassAccessExceptionClass = null;
|
if ((f.getName().contains("Private") ||
|
(!same_package && f.getName().contains("Package")) ||
|
(!same_package && f.getName().contains("Protected"))) &&
|
!(protected_class && f.getName().contains("Public"))) {
|
mainClassAccessExceptionClass = IllegalAccessException.class;
|
}
|
|
this.getValue(f, validInst, typeChar, subClassAccessExceptionClass);
|
localInst.getValue(f, validInst, typeChar, mainClassAccessExceptionClass);
|
|
// Check things that can get beyond the IllegalAccessException.
|
if (subClassAccessExceptionClass == null) {
|
// Check NPE.
|
Class<?> npeClass = null;
|
if (!f.getName().contains("Static")) {
|
npeClass = NullPointerException.class;
|
}
|
|
this.getValue(f, null, typeChar, npeClass);
|
if (mainClassAccessExceptionClass == null) {
|
localInst.getValue(f, null, typeChar, npeClass);
|
}
|
|
// Check access of wrong field type for valid instance.
|
for (int i = 0; i < typeChars.length(); i++) {
|
char otherChar = typeChars.charAt(i);
|
Class<?> illArgClass = compatibleTypes(typeChar, otherChar) ?
|
null : IllegalArgumentException.class;
|
this.getValue(f, validInst, otherChar, illArgClass);
|
if (mainClassAccessExceptionClass == null) {
|
localInst.getValue(f, validInst, otherChar, illArgClass);
|
}
|
}
|
|
if (!f.getName().contains("Static")) {
|
// Wrong object.
|
this.getValue(f, plainObj, typeChar, IllegalArgumentException.class);
|
if (mainClassAccessExceptionClass == null) {
|
localInst.getValue(f, plainObj, typeChar, IllegalArgumentException.class);
|
}
|
}
|
}
|
}
|
|
for (Method m : methods) {
|
Class<?> subClassAccessExceptionClass = null;
|
if (m.getName().contains("Private") ||
|
(!same_package && m.getName().contains("Package")) ||
|
(!same_package && m.getName().contains("Protected"))) {
|
subClassAccessExceptionClass = IllegalAccessException.class;
|
}
|
this.invoke(m, validInst, subClassAccessExceptionClass);
|
}
|
}
|
System.out.println("good");
|
}
|
|
/*
|
* [this is a clone of Main.getValue() -- the class issuing the
|
* reflection call is significant]
|
*/
|
public Object getValue(Field field, Object obj, char type,
|
Class<?> expectedException) {
|
Object result = null;
|
try {
|
switch (type) {
|
case 'Z':
|
result = field.getBoolean(obj);
|
break;
|
case 'B':
|
result = field.getByte(obj);
|
break;
|
case 'S':
|
result = field.getShort(obj);
|
break;
|
case 'C':
|
result = field.getChar(obj);
|
break;
|
case 'I':
|
result = field.getInt(obj);
|
break;
|
case 'J':
|
result = field.getLong(obj);
|
break;
|
case 'F':
|
result = field.getFloat(obj);
|
break;
|
case 'D':
|
result = field.getDouble(obj);
|
break;
|
case 'L':
|
result = field.get(obj);
|
break;
|
default:
|
throw new RuntimeException("bad type '" + type + "'");
|
}
|
|
/* success; expected? */
|
if (expectedException != null) {
|
System.out.println("ERROR: call succeeded for field " + field +
|
" with a read of type '" + type +
|
"', was expecting " + expectedException);
|
Thread.dumpStack();
|
}
|
} catch (Exception ex) {
|
if (expectedException == null) {
|
System.out.println("ERROR: call failed unexpectedly: "
|
+ ex.getClass());
|
ex.printStackTrace(System.out);
|
} else {
|
if (!expectedException.equals(ex.getClass())) {
|
System.out.println("ERROR: incorrect exception: wanted "
|
+ expectedException.getName() + ", got "
|
+ ex.getClass());
|
ex.printStackTrace(System.out);
|
}
|
}
|
}
|
|
return result;
|
}
|
|
public Object invoke(Method method, Object obj, Class<?> expectedException) {
|
Object result = null;
|
try {
|
result = method.invoke(obj);
|
/* success; expected? */
|
if (expectedException != null) {
|
System.out.println("ERROR: call succeeded for method " + method + "', was expecting " +
|
expectedException);
|
Thread.dumpStack();
|
}
|
} catch (Exception ex) {
|
if (expectedException == null) {
|
System.out.println("ERROR: call failed unexpectedly: " + ex.getClass());
|
ex.printStackTrace(System.out);
|
} else {
|
if (!expectedException.equals(ex.getClass())) {
|
System.out.println("ERROR: incorrect exception: wanted " + expectedException.getName() +
|
", got " + ex.getClass());
|
ex.printStackTrace(System.out);
|
}
|
}
|
}
|
return result;
|
}
|
}
|