1/*
2 * Copyright (C) 2006 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
17import java.lang.reflect.*;
18import java.io.IOException;
19import java.util.Collections;
20import java.util.ArrayList;
21import java.util.Arrays;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
25
26/**
27 * Reflection test.
28 */
29public class Main {
30    private static boolean FULL_ACCESS_CHECKS = false;  // b/5861201
31    public Main() {}
32    public Main(ArrayList<Integer> stuff) {}
33
34    void printMethodInfo(Method meth) {
35        Class[] params, exceptions;
36        int i;
37
38        System.out.println("Method name is " + meth.getName());
39        System.out.println(" Declaring class is "
40            + meth.getDeclaringClass().getName());
41        params = meth.getParameterTypes();
42        for (i = 0; i < params.length; i++)
43            System.out.println(" Arg " + i + ": " + params[i].getName());
44        exceptions = meth.getExceptionTypes();
45        for (i = 0; i < exceptions.length; i++)
46            System.out.println(" Exc " + i + ": " + exceptions[i].getName());
47        System.out.println(" Return type is " + meth.getReturnType().getName());
48        System.out.println(" Access flags are 0x"
49            + Integer.toHexString(meth.getModifiers()));
50        //System.out.println(" GenericStr is " + meth.toGenericString());
51    }
52
53    void printFieldInfo(Field field) {
54        System.out.println("Field name is " + field.getName());
55        System.out.println(" Declaring class is "
56            + field.getDeclaringClass().getName());
57        System.out.println(" Field type is " + field.getType().getName());
58        System.out.println(" Access flags are 0x"
59            + Integer.toHexString(field.getModifiers()));
60    }
61
62    private void showStrings(Target instance)
63        throws NoSuchFieldException, IllegalAccessException {
64
65        Class target = Target.class;
66        String one, two, three, four;
67        Field field = null;
68
69        field = target.getField("string1");
70        one = (String) field.get(instance);
71
72        field = target.getField("string2");
73        two = (String) field.get(instance);
74
75        field = target.getField("string3");
76        three = (String) field.get(instance);
77
78        System.out.println("  ::: " + one + ":" + two + ":" + three);
79    }
80
81    public static void checkAccess() {
82        try {
83            Class target = otherpackage.Other.class;
84            Object instance = new otherpackage.Other();
85            Method meth;
86
87            meth = target.getMethod("publicMethod", (Class[]) null);
88            meth.invoke(instance);
89
90            try {
91                meth = target.getMethod("packageMethod", (Class[]) null);
92                System.err.println("succeeded on package-scope method");
93            } catch (NoSuchMethodException nsme) {
94                // good
95            }
96
97
98            instance = otherpackage.Other.getInnerClassInstance();
99            target = instance.getClass();
100            meth = target.getMethod("innerMethod", (Class[]) null);
101            try {
102                if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
103                meth.invoke(instance);
104                System.err.println("inner-method invoke unexpectedly worked");
105            } catch (IllegalAccessException iae) {
106                // good
107            }
108
109            Field field = target.getField("innerField");
110            try {
111                int x = field.getInt(instance);
112                if (!FULL_ACCESS_CHECKS) { throw new IllegalAccessException(); }
113                System.err.println("field get unexpectedly worked: " + x);
114            } catch (IllegalAccessException iae) {
115                // good
116            }
117        } catch (Exception ex) {
118            System.out.println("----- unexpected exception -----");
119            ex.printStackTrace();
120        }
121    }
122
123    public void run() {
124        Class target = Target.class;
125        Method meth = null;
126        Field field = null;
127        boolean excep;
128
129        try {
130            meth = target.getMethod("myMethod", new Class[] { int.class });
131
132            if (meth.getDeclaringClass() != target)
133                throw new RuntimeException();
134            printMethodInfo(meth);
135
136            meth = target.getMethod("myMethod", new Class[] { float.class });
137            printMethodInfo(meth);
138
139            meth = target.getMethod("myNoargMethod", (Class[]) null);
140            printMethodInfo(meth);
141
142            meth = target.getMethod("myMethod",
143                new Class[] { String[].class, float.class, char.class });
144            printMethodInfo(meth);
145
146            Target instance = new Target();
147            Object[] argList = new Object[] {
148                new String[] { "hi there" },
149                new Float(3.1415926f),
150                new Character('\u2714')
151            };
152            System.out.println("Before, float is "
153                + ((Float)argList[1]).floatValue());
154
155            Integer boxval;
156            boxval = (Integer) meth.invoke(instance, argList);
157            System.out.println("Result of invoke: " + boxval.intValue());
158
159            System.out.println("Calling no-arg void-return method");
160            meth = target.getMethod("myNoargMethod", (Class[]) null);
161            meth.invoke(instance, (Object[]) null);
162
163            /* try invoking a method that throws an exception */
164            meth = target.getMethod("throwingMethod", (Class[]) null);
165            try {
166                meth.invoke(instance, (Object[]) null);
167                System.out.println("GLITCH: didn't throw");
168            } catch (InvocationTargetException ite) {
169                System.out.println("Invoke got expected exception:");
170                System.out.println(ite.getClass().getName());
171                System.out.println(ite.getCause());
172            }
173            catch (Exception ex) {
174                System.out.println("GLITCH: invoke got wrong exception:");
175                ex.printStackTrace();
176            }
177            System.out.println("");
178
179
180            field = target.getField("string1");
181            if (field.getDeclaringClass() != target)
182                throw new RuntimeException();
183            printFieldInfo(field);
184            String strVal = (String) field.get(instance);
185            System.out.println("  string1 value is '" + strVal + "'");
186
187            showStrings(instance);
188
189            field.set(instance, new String("a new string"));
190            strVal = (String) field.get(instance);
191            System.out.println("  string1 value is now '" + strVal + "'");
192
193            showStrings(instance);
194
195            try {
196                field.set(instance, new Object());
197                System.out.println("WARNING: able to store Object into String");
198            }
199            catch (IllegalArgumentException iae) {
200                System.out.println("  got expected illegal obj store exc");
201            }
202
203
204            try {
205                String four;
206                field = target.getField("string4");
207                four = (String) field.get(instance);
208                System.out.println("WARNING: able to access string4: "
209                    + four);
210            }
211            catch (IllegalAccessException iae) {
212                System.out.println("  got expected access exc");
213            }
214            catch (NoSuchFieldException nsfe) {
215                System.out.println("  got the other expected access exc");
216            }
217            try {
218                String three;
219                field = target.getField("string3");
220                three = (String) field.get(this);
221                System.out.println("WARNING: able to get string3 in wrong obj: "
222                    + three);
223            }
224            catch (IllegalArgumentException iae) {
225                System.out.println("  got expected arg exc");
226            }
227
228            /*
229             * Try setting a field to null.
230             */
231            String four;
232            field = target.getDeclaredField("string3");
233            field.set(instance, null);
234
235            /*
236             * Try getDeclaredField on a non-existant field.
237             */
238            try {
239                field = target.getDeclaredField("nonExistant");
240                System.out.println("ERROR: Expected NoSuchFieldException");
241            } catch (NoSuchFieldException nsfe) {
242                String msg = nsfe.getMessage();
243                if (!msg.contains("Target;")) {
244                    System.out.println("  NoSuchFieldException '" + msg +
245                        "' didn't contain class");
246                }
247            }
248
249            /*
250             * Do some stuff with long.
251             */
252            long longVal;
253            field = target.getField("pubLong");
254            longVal = field.getLong(instance);
255            System.out.println("pubLong initial value is " +
256                Long.toHexString(longVal));
257            field.setLong(instance, 0x9988776655443322L);
258            longVal = field.getLong(instance);
259            System.out.println("pubLong new value is " +
260                Long.toHexString(longVal));
261
262
263            field = target.getField("superInt");
264            if (field.getDeclaringClass() == target)
265                throw new RuntimeException();
266            printFieldInfo(field);
267            int intVal = field.getInt(instance);
268            System.out.println("  superInt value is " + intVal);
269            Integer boxedIntVal = (Integer) field.get(instance);
270            System.out.println("  superInt boxed is " + boxedIntVal);
271
272            field.set(instance, new Integer(20202));
273            intVal = field.getInt(instance);
274            System.out.println("  superInt value is now " + intVal);
275            field.setShort(instance, (short)30303);
276            intVal = field.getInt(instance);
277            System.out.println("  superInt value (from short) is now " +intVal);
278            field.setInt(instance, 40404);
279            intVal = field.getInt(instance);
280            System.out.println("  superInt value is now " + intVal);
281            try {
282                field.set(instance, new Long(123));
283                System.out.println("FAIL: expected exception not thrown");
284            }
285            catch (IllegalArgumentException iae) {
286                System.out.println("  got expected long->int failure");
287            }
288            try {
289                field.setLong(instance, 123);
290                System.out.println("FAIL: expected exception not thrown");
291            }
292            catch (IllegalArgumentException iae) {
293                System.out.println("  got expected long->int failure");
294            }
295            try {
296                field.set(instance, new String("abc"));
297                System.out.println("FAIL: expected exception not thrown");
298            }
299            catch (IllegalArgumentException iae) {
300                System.out.println("  got expected string->int failure");
301            }
302
303            try {
304                field.getShort(instance);
305                System.out.println("FAIL: expected exception not thrown");
306            }
307            catch (IllegalArgumentException iae) {
308                System.out.println("  got expected int->short failure");
309            }
310
311            field = target.getField("superClassInt");
312            printFieldInfo(field);
313            int superClassIntVal = field.getInt(instance);
314            System.out.println("  superClassInt value is " + superClassIntVal);
315
316            field = target.getField("staticDouble");
317            printFieldInfo(field);
318            double staticDoubleVal = field.getDouble(null);
319            System.out.println("  staticDoubleVal value is " + staticDoubleVal);
320
321            try {
322                field.getLong(instance);
323                System.out.println("FAIL: expected exception not thrown");
324            }
325            catch (IllegalArgumentException iae) {
326                System.out.println("  got expected double->long failure");
327            }
328
329            excep = false;
330            try {
331                field = target.getField("aPrivateInt");
332                printFieldInfo(field);
333            }
334            catch (NoSuchFieldException nsfe) {
335                System.out.println("as expected: aPrivateInt not found");
336                excep = true;
337            }
338            if (!excep)
339                System.out.println("BUG: got aPrivateInt");
340
341
342            field = target.getField("constantString");
343            printFieldInfo(field);
344            String val = (String) field.get(instance);
345            System.out.println("  Constant test value is " + val);
346
347
348            field = target.getField("cantTouchThis");
349            printFieldInfo(field);
350            intVal = field.getInt(instance);
351            System.out.println("  cantTouchThis is " + intVal);
352            try {
353                field.setInt(instance, 99);
354                System.out.println("ERROR: set-final did not throw exception");
355            } catch (IllegalAccessException iae) {
356                System.out.println("  as expected: set-final throws exception");
357            }
358            intVal = field.getInt(instance);
359            System.out.println("  cantTouchThis is still " + intVal);
360
361            System.out.println("  " + field + " accessible=" + field.isAccessible());
362            field.setAccessible(true);
363            System.out.println("  " + field + " accessible=" + field.isAccessible());
364            field.setInt(instance, 87);     // exercise int version
365            intVal = field.getInt(instance);
366            System.out.println("  cantTouchThis is now " + intVal);
367            field.set(instance, 88);        // exercise Object version
368            intVal = field.getInt(instance);
369            System.out.println("  cantTouchThis is now " + intVal);
370
371            Constructor<Target> cons;
372            Target targ;
373            Object[] args;
374
375            cons = target.getConstructor(new Class[] { int.class,float.class });
376            args = new Object[] { new Integer(7), new Float(3.3333) };
377            System.out.println("cons modifiers=" + cons.getModifiers());
378            targ = cons.newInstance(args);
379            targ.myMethod(17);
380
381            try {
382                Thrower thrower = Thrower.class.newInstance();
383                System.out.println("ERROR: Class.newInstance did not throw exception");
384            } catch (UnsupportedOperationException uoe) {
385                System.out.println("got expected exception for Class.newInstance");
386            } catch (Exception e) {
387                System.out.println("ERROR: Class.newInstance got unexpected exception: " +
388                                   e.getClass().getName());
389            }
390
391            try {
392                Constructor<Thrower> constructor = Thrower.class.getDeclaredConstructor();
393                Thrower thrower = constructor.newInstance();
394                System.out.println("ERROR: Constructor.newInstance did not throw exception");
395            } catch (InvocationTargetException ite) {
396                System.out.println("got expected exception for Constructor.newInstance");
397            } catch (Exception e) {
398                System.out.println("ERROR: Constructor.newInstance got unexpected exception: " +
399                                   e.getClass().getName());
400            }
401
402        } catch (Exception ex) {
403            System.out.println("----- unexpected exception -----");
404            ex.printStackTrace();
405        }
406
407        System.out.println("ReflectTest done!");
408    }
409
410    public static void checkSwap() {
411        Method m;
412
413        final Object[] objects = new Object[2];
414        try {
415            m = Collections.class.getDeclaredMethod("swap",
416                            Object[].class, int.class, int.class);
417        } catch (NoSuchMethodException nsme) {
418            nsme.printStackTrace();
419            return;
420        }
421        System.out.println(m + " accessible=" + m.isAccessible());
422        m.setAccessible(true);
423        System.out.println(m + " accessible=" + m.isAccessible());
424        try {
425            m.invoke(null, objects, 0, 1);
426        } catch (IllegalAccessException iae) {
427            iae.printStackTrace();
428            return;
429        } catch (InvocationTargetException ite) {
430            ite.printStackTrace();
431            return;
432        }
433
434        try {
435            String s = "Should be ignored";
436            m.invoke(s, objects, 0, 1);
437        } catch (IllegalAccessException iae) {
438            iae.printStackTrace();
439            return;
440        } catch (InvocationTargetException ite) {
441            ite.printStackTrace();
442            return;
443        }
444
445        try {
446            System.out.println("checkType invoking null");
447            // Trigger an NPE at the target.
448            m.invoke(null, null, 0, 1);
449            System.out.println("ERROR: should throw InvocationTargetException");
450        } catch (InvocationTargetException ite) {
451            System.out.println("checkType got expected exception");
452        } catch (IllegalAccessException iae) {
453            iae.printStackTrace();
454            return;
455        }
456    }
457
458    public static void checkClinitForFields() throws Exception {
459      // Loading a class constant shouldn't run <clinit>.
460      System.out.println("calling const-class FieldNoisyInitUser.class");
461      Class niuClass = FieldNoisyInitUser.class;
462      System.out.println("called const-class FieldNoisyInitUser.class");
463
464      // Getting the declared fields doesn't run <clinit>.
465      Field[] fields = niuClass.getDeclaredFields();
466      System.out.println("got fields");
467
468      Field field = niuClass.getField("staticField");
469      System.out.println("got field");
470      field.get(null);
471      System.out.println("read field value");
472
473      // FieldNoisyInitUser should now be initialized, but FieldNoisyInit shouldn't be initialized yet.
474      FieldNoisyInitUser niu = new FieldNoisyInitUser();
475      FieldNoisyInit ni = new FieldNoisyInit();
476
477      System.out.println("");
478    }
479
480    public static void checkClinitForMethods() throws Exception {
481      // Loading a class constant shouldn't run <clinit>.
482      System.out.println("calling const-class MethodNoisyInitUser.class");
483      Class niuClass = MethodNoisyInitUser.class;
484      System.out.println("called const-class MethodNoisyInitUser.class");
485
486      // Getting the declared methods doesn't run <clinit>.
487      Method[] methods = niuClass.getDeclaredMethods();
488      System.out.println("got methods");
489
490      Method method = niuClass.getMethod("staticMethod", (Class[]) null);
491      System.out.println("got method");
492      method.invoke(null);
493      System.out.println("invoked method");
494
495      // MethodNoisyInitUser should now be initialized, but MethodNoisyInit shouldn't be initialized yet.
496      MethodNoisyInitUser niu = new MethodNoisyInitUser();
497      MethodNoisyInit ni = new MethodNoisyInit();
498
499      System.out.println("");
500    }
501
502
503    /*
504     * Test some generic type stuff.
505     */
506    public List<String> dummy;
507    public Map<Integer,String> fancyMethod(ArrayList<String> blah) { return null; }
508    public static void checkGeneric() {
509        Field field;
510        try {
511            field = Main.class.getField("dummy");
512        } catch (NoSuchFieldException nsfe) {
513            throw new RuntimeException(nsfe);
514        }
515        Type listType = field.getGenericType();
516        System.out.println("generic field: " + listType);
517
518        Method method;
519        try {
520            method = Main.class.getMethod("fancyMethod",
521                new Class[] { ArrayList.class });
522        } catch (NoSuchMethodException nsme) {
523            throw new RuntimeException(nsme);
524        }
525        Type[] parmTypes = method.getGenericParameterTypes();
526        Type ret = method.getGenericReturnType();
527        System.out.println("generic method " + method.getName() + " params='"
528            + stringifyTypeArray(parmTypes) + "' ret='" + ret + "'");
529
530        Constructor ctor;
531        try {
532            ctor = Main.class.getConstructor(new Class[] { ArrayList.class });
533        } catch (NoSuchMethodException nsme) {
534            throw new RuntimeException(nsme);
535        }
536        parmTypes = ctor.getGenericParameterTypes();
537        System.out.println("generic ctor " + ctor.getName() + " params='"
538            + stringifyTypeArray(parmTypes) + "'");
539    }
540
541    /*
542     * Convert an array of Type into a string.  Start with an array count.
543     */
544    private static String stringifyTypeArray(Type[] types) {
545        StringBuilder stb = new StringBuilder();
546        boolean first = true;
547
548        stb.append("[" + types.length + "]");
549
550        for (Type t: types) {
551            if (first) {
552                stb.append(" ");
553                first = false;
554            } else {
555                stb.append(", ");
556            }
557            stb.append(t.toString());
558        }
559
560        return stb.toString();
561    }
562
563    public static void checkUnique() {
564        Field field1, field2;
565        try {
566            field1 = Main.class.getField("dummy");
567            field2 = Main.class.getField("dummy");
568        } catch (NoSuchFieldException nsfe) {
569            throw new RuntimeException(nsfe);
570        }
571        if (field1 == field2) {
572            System.out.println("ERROR: fields shouldn't have reference equality");
573        } else {
574            System.out.println("fields are unique");
575        }
576        if (field1.hashCode() == field2.hashCode() && field1.equals(field2)) {
577            System.out.println("fields are .equals");
578        } else {
579            System.out.println("ERROR: fields fail equality");
580        }
581        Method method1, method2;
582        try {
583            method1 = Main.class.getMethod("fancyMethod", new Class[] { ArrayList.class });
584            method2 = Main.class.getMethod("fancyMethod", new Class[] { ArrayList.class });
585        } catch (NoSuchMethodException nsme) {
586            throw new RuntimeException(nsme);
587        }
588        if (method1 == method2) {
589            System.out.println("ERROR: methods shouldn't have reference equality");
590        } else {
591            System.out.println("methods are unique");
592        }
593        if (method1.hashCode() == method2.hashCode() && method1.equals(method2)) {
594            System.out.println("methods are .equals");
595        } else {
596            System.out.println("ERROR: methods fail equality");
597        }
598    }
599
600    public static void checkParametrizedTypeEqualsAndHashCode() {
601        Method method1;
602        Method method2;
603        Method method3;
604        try {
605            method1 = ParametrizedTypeTest.class.getDeclaredMethod("aMethod", Set.class);
606            method2 = ParametrizedTypeTest.class.getDeclaredMethod("aMethod", Set.class);
607            method3 = ParametrizedTypeTest.class.getDeclaredMethod("aMethodIdentical", Set.class);
608        } catch (NoSuchMethodException nsme) {
609            throw new RuntimeException(nsme);
610        }
611
612        List<Type> types1 = Arrays.asList(method1.getGenericParameterTypes());
613        List<Type> types2 = Arrays.asList(method2.getGenericParameterTypes());
614        List<Type> types3 = Arrays.asList(method3.getGenericParameterTypes());
615
616        Type type1 = types1.get(0);
617        Type type2 = types2.get(0);
618        Type type3 = types3.get(0);
619
620        if (type1 instanceof ParameterizedType) {
621            System.out.println("type1 is a ParameterizedType");
622        }
623        if (type2 instanceof ParameterizedType) {
624            System.out.println("type2 is a ParameterizedType");
625        }
626        if (type3 instanceof ParameterizedType) {
627            System.out.println("type3 is a ParameterizedType");
628        }
629
630        if (type1.equals(type2)) {
631            System.out.println("type1("+type1+") equals type2("+type2+")");
632        } else {
633            System.out.println("type1("+type1+") does not equal type2("+type2+")");
634        }
635
636        if (type1.equals(type3)) {
637            System.out.println("type1("+type1+") equals type3("+type3+")");
638        } else {
639            System.out.println("type1("+type1+") does not equal type3("+type3+")");
640        }
641        if (type1.hashCode() == type2.hashCode()) {
642            System.out.println("type1("+type1+") hashCode equals type2("+type2+") hashCode");
643        } else {
644            System.out.println(
645                   "type1("+type1+") hashCode does not equal type2("+type2+") hashCode");
646        }
647
648        if (type1.hashCode() == type3.hashCode()) {
649            System.out.println("type1("+type1+") hashCode equals type3("+type3+") hashCode");
650        } else {
651            System.out.println(
652                    "type1("+type1+") hashCode does not equal type3("+type3+") hashCode");
653        }
654    }
655
656    public static void checkGenericArrayTypeEqualsAndHashCode() {
657        Method method1;
658        Method method2;
659        Method method3;
660        try {
661            method1 = GenericArrayTypeTest.class.getDeclaredMethod("aMethod", Object[].class);
662            method2 = GenericArrayTypeTest.class.getDeclaredMethod("aMethod", Object[].class);
663            method3 = GenericArrayTypeTest.class.getDeclaredMethod("aMethodIdentical", Object[].class);
664        } catch (NoSuchMethodException nsme) {
665            throw new RuntimeException(nsme);
666        }
667
668        List<Type> types1 = Arrays.asList(method1.getGenericParameterTypes());
669        List<Type> types2 = Arrays.asList(method2.getGenericParameterTypes());
670        List<Type> types3 = Arrays.asList(method3.getGenericParameterTypes());
671
672        Type type1 = types1.get(0);
673        Type type2 = types2.get(0);
674        Type type3 = types3.get(0);
675
676        if (type1 instanceof GenericArrayType) {
677            System.out.println("type1 is a GenericArrayType");
678        }
679        if (type2 instanceof GenericArrayType) {
680            System.out.println("type2 is a GenericArrayType");
681        }
682        if (type3 instanceof GenericArrayType) {
683            System.out.println("type3 is a GenericArrayType");
684        }
685
686        if (type1.equals(type2)) {
687            System.out.println("type1("+type1+") equals type2("+type2+")");
688        } else {
689            System.out.println("type1("+type1+") does not equal type2("+type2+")");
690        }
691
692        if (type1.equals(type3)) {
693            System.out.println("type1("+type1+") equals type3("+type3+")");
694        } else {
695            System.out.println("type1("+type1+") does not equal type3("+type3+")");
696        }
697        if (type1.hashCode() == type2.hashCode()) {
698            System.out.println("type1("+type1+") hashCode equals type2("+type2+") hashCode");
699        } else {
700            System.out.println(
701                   "type1("+type1+") hashCode does not equal type2("+type2+") hashCode");
702        }
703
704        if (type1.hashCode() == type3.hashCode()) {
705            System.out.println("type1("+type1+") hashCode equals type3("+type3+") hashCode");
706        } else {
707            System.out.println(
708                    "type1("+type1+") hashCode does not equal type3("+type3+") hashCode");
709        }
710    }
711
712    private static void checkGetDeclaredConstructor() {
713        try {
714            Method.class.getDeclaredConstructor().setAccessible(true);
715            System.out.println("Didn't get an exception from Method.class.getDeclaredConstructor().setAccessible");
716        } catch (SecurityException e) {
717        } catch (NoSuchMethodException e) {
718        } catch (Exception e) {
719            System.out.println(e);
720        }
721        try {
722            Field.class.getDeclaredConstructor().setAccessible(true);
723            System.out.println("Didn't get an exception from Field.class.getDeclaredConstructor().setAccessible");
724        } catch (SecurityException e) {
725        } catch (NoSuchMethodException e) {
726        } catch (Exception e) {
727            System.out.println(e);
728        }
729        try {
730            Class.class.getDeclaredConstructor().setAccessible(true);
731            System.out.println("Didn't get an exception from Class.class.getDeclaredConstructor().setAccessible");
732        } catch (SecurityException e) {
733        } catch (NoSuchMethodException e) {
734        } catch (Exception e) {
735            System.out.println(e);
736        }
737    }
738
739    static void checkPrivateFieldAccess() {
740        (new OtherClass()).test();
741    }
742
743    public static void main(String[] args) throws Exception {
744        Main test = new Main();
745        test.run();
746
747        checkGetDeclaredConstructor();
748        checkAccess();
749        checkSwap();
750        checkClinitForFields();
751        checkClinitForMethods();
752        checkGeneric();
753        checkUnique();
754        checkParametrizedTypeEqualsAndHashCode();
755        checkGenericArrayTypeEqualsAndHashCode();
756        checkPrivateFieldAccess();
757    }
758}
759
760
761class SuperTarget {
762    public SuperTarget() {
763        System.out.println("SuperTarget constructor ()V");
764        superInt = 1010101;
765        superClassInt = 1010102;
766    }
767
768    public int myMethod(float floatArg) {
769        System.out.println("myMethod (F)I " + floatArg);
770        return 6;
771    }
772
773    public int superInt;
774    public static int superClassInt;
775}
776
777class Target extends SuperTarget {
778    public Target() {
779        System.out.println("Target constructor ()V");
780    }
781
782    public Target(int ii, float ff) {
783        System.out.println("Target constructor (IF)V : ii="
784            + ii + " ff=" + ff);
785        anInt = ii;
786    }
787
788    public int myMethod(int intarg) throws NullPointerException, IOException {
789        System.out.println("myMethod (I)I");
790        System.out.println(" arg=" + intarg + " anInt=" + anInt);
791        return 5;
792    }
793
794    public int myMethod(String[] strarg, float f, char c) {
795        System.out.println("myMethod: " + strarg[0] + " " + f + " " + c + " !");
796        return 7;
797    }
798
799    public static void myNoargMethod() {
800        System.out.println("myNoargMethod ()V");
801    }
802
803    public void throwingMethod() {
804        System.out.println("throwingMethod");
805        throw new NullPointerException("gratuitous throw!");
806    }
807
808    public void misc() {
809        System.out.println("misc");
810    }
811
812    public int anInt;
813    public String string1 = "hey";
814    public String string2 = "yo";
815    public String string3 = "there";
816    private String string4 = "naughty";
817    public static final String constantString = "a constant string";
818    private int aPrivateInt;
819
820    public final int cantTouchThis = 77;
821
822    public long pubLong = 0x1122334455667788L;
823
824    public static double staticDouble = 3.3;
825}
826
827class FieldNoisyInit {
828    static {
829        System.out.println("FieldNoisyInit is initializing");
830        //Throwable th = new Throwable();
831        //th.printStackTrace();
832    }
833}
834
835class FieldNoisyInitUser {
836    static {
837        System.out.println("FieldNoisyInitUser is initializing");
838    }
839    public static int staticField;
840    public static FieldNoisyInit noisy;
841}
842
843class MethodNoisyInit {
844    static {
845        System.out.println("MethodNoisyInit is initializing");
846        //Throwable th = new Throwable();
847        //th.printStackTrace();
848    }
849}
850
851class MethodNoisyInitUser {
852    static {
853        System.out.println("MethodNoisyInitUser is initializing");
854    }
855    public static void staticMethod() {}
856    public void createMethodNoisyInit(MethodNoisyInit ni) {}
857}
858
859class Thrower {
860    public Thrower() throws UnsupportedOperationException {
861        throw new UnsupportedOperationException();
862    }
863}
864
865class ParametrizedTypeTest {
866    public void aMethod(Set<String> names) {}
867    public void aMethodIdentical(Set<String> names) {}
868}
869
870class GenericArrayTypeTest<T> {
871    public void aMethod(T[] names) {}
872    public void aMethodIdentical(T[] names) {}
873}
874
875class OtherClass {
876    private static final long LONG = 1234;
877    public void test() {
878        try {
879            Field field = getClass().getDeclaredField("LONG");
880            if (1234 != field.getLong(null)) {
881              System.out.println("ERROR: values don't match");
882            }
883        } catch (Exception e) {
884            System.out.println(e);
885        }
886    }
887}
888