1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.lang;
19
20import java.io.File;
21import java.io.FileInputStream;
22import java.io.FileOutputStream;
23import java.io.InputStream;
24import java.io.Serializable;
25import java.lang.reflect.Constructor;
26import java.lang.reflect.Field;
27import java.lang.reflect.Member;
28import java.lang.reflect.Method;
29import java.lang.reflect.Modifier;
30import java.net.URL;
31import java.net.URLClassLoader;
32import java.security.AccessControlContext;
33import java.security.AccessController;
34import java.security.BasicPermission;
35import java.security.DomainCombiner;
36import java.security.Permission;
37import java.security.PrivilegedAction;
38import java.security.ProtectionDomain;
39import java.security.Security;
40import java.util.Arrays;
41import java.util.List;
42import java.util.Vector;
43
44import tests.support.resource.Support_Resources;
45
46public class ClassTest extends junit.framework.TestCase {
47
48    public static final String FILENAME = ClassTest.class.getPackage().getName().replace('.', '/')+"/test#.properties";
49
50    static class StaticMember$Class {
51        class Member2$A {
52        }
53    }
54
55    class Member$Class {
56        class Member3$B {
57        }
58    }
59
60    public static class TestClass {
61        @SuppressWarnings("unused")
62        private int privField = 1;
63
64        public int pubField = 2;
65
66        private Object cValue = null;
67
68        public Object ack = new Object();
69
70        @SuppressWarnings("unused")
71        private int privMethod() {
72            return 1;
73        }
74
75        public int pubMethod() {
76            return 2;
77        }
78
79        public Object cValue() {
80            return cValue;
81        }
82
83        public TestClass() {
84        }
85
86        @SuppressWarnings("unused")
87        private TestClass(Object o) {
88        }
89    }
90
91    public static class SubTestClass extends TestClass {
92    }
93
94    /**
95     * @tests java.lang.Class#forName(java.lang.String)
96     */
97    public void test_forNameLjava_lang_String() throws Exception {
98        assertSame("Class for name failed for java.lang.Object",
99                   Object.class, Class.forName("java.lang.Object"));
100        assertSame("Class for name failed for [[Ljava.lang.Object;",
101                   Object[][].class, Class.forName("[[Ljava.lang.Object;"));
102
103        assertSame("Class for name failed for [I",
104                   int[].class, Class.forName("[I"));
105
106        try {
107            Class.forName("int");
108            fail();
109        } catch (ClassNotFoundException e) {
110        }
111
112        try {
113            Class.forName("byte");
114            fail();
115        } catch (ClassNotFoundException e) {
116        }
117        try {
118            Class.forName("char");
119            fail();
120        } catch (ClassNotFoundException e) {
121        }
122
123        try {
124            Class.forName("void");
125            fail();
126        } catch (ClassNotFoundException e) {
127        }
128
129        try {
130            Class.forName("short");
131            fail();
132        } catch (ClassNotFoundException e) {
133        }
134        try {
135            Class.forName("long");
136            fail();
137        } catch (ClassNotFoundException e) {
138        }
139
140        try {
141            Class.forName("boolean");
142            fail();
143        } catch (ClassNotFoundException e) {
144        }
145        try {
146            Class.forName("float");
147            fail();
148        } catch (ClassNotFoundException e) {
149        }
150        try {
151            Class.forName("double");
152            fail();
153        } catch (ClassNotFoundException e) {
154        }
155
156        //regression test for JIRA 2162
157        try {
158            Class.forName("%");
159            fail("should throw ClassNotFoundException.");
160        } catch (ClassNotFoundException e) {
161        }
162
163        //Regression Test for HARMONY-3332
164        String securityProviderClassName;
165        int count = 1;
166        while ((securityProviderClassName = Security
167                .getProperty("security.provider." + count++)) != null) {
168            Class.forName(securityProviderClassName);
169        }
170    }
171
172    /**
173     * @tests java.lang.Class#getClasses()
174     */
175    public void test_getClasses() {
176        assertEquals("Incorrect class array returned",
177                     2, ClassTest.class.getClasses().length);
178    }
179
180    /**
181     * @tests java.lang.Class#getClasses()
182     */
183    public void test_getClasses_subtest0() {
184        final Permission privCheckPermission = new BasicPermission("Privilege check") {
185            private static final long serialVersionUID = 1L;
186        };
187
188        class MyCombiner implements DomainCombiner {
189            boolean combine;
190
191            public ProtectionDomain[] combine(ProtectionDomain[] executionDomains,
192                    ProtectionDomain[] parentDomains) {
193                combine = true;
194                return new ProtectionDomain[0];
195            }
196
197            private boolean recurring = false;
198
199            public boolean isPriviledged() {
200                if (recurring) {
201                    return true;
202                }
203                try {
204                    recurring = true;
205                    combine = false;
206                    try {
207                        AccessController.checkPermission(privCheckPermission);
208                    } catch (SecurityException e) {}
209                    return !combine;
210                } finally {
211                    recurring = false;
212                }
213            }
214        }
215    }
216
217    /**
218     * @tests java.lang.Class#getComponentType()
219     */
220    public void test_getComponentType() {
221        assertSame("int array does not have int component type", int.class, int[].class
222                .getComponentType());
223        assertSame("Object array does not have Object component type", Object.class,
224                Object[].class.getComponentType());
225        assertNull("Object has non-null component type", Object.class.getComponentType());
226    }
227
228    /**
229     * @tests java.lang.Class#getConstructor(java.lang.Class[])
230     */
231    public void test_getConstructor$Ljava_lang_Class()
232        throws NoSuchMethodException {
233        TestClass.class.getConstructor(new Class[0]);
234        try {
235            TestClass.class.getConstructor(Object.class);
236            fail("Found private constructor");
237        } catch (NoSuchMethodException e) {
238            // Correct - constructor with obj is private
239        }
240    }
241
242    /**
243     * @tests java.lang.Class#getConstructors()
244     */
245    public void test_getConstructors() throws Exception {
246        Constructor[] c = TestClass.class.getConstructors();
247        assertEquals("Incorrect number of constructors returned", 1, c.length);
248    }
249
250    /**
251     * @tests java.lang.Class#getDeclaredClasses()
252     */
253    public void test_getDeclaredClasses() {
254        assertEquals("Incorrect class array returned", 2, ClassTest.class.getClasses().length);
255    }
256
257    /**
258     * @tests java.lang.Class#getDeclaredConstructor(java.lang.Class[])
259     */
260    public void test_getDeclaredConstructor$Ljava_lang_Class() throws Exception {
261        Constructor<TestClass> c = TestClass.class.getDeclaredConstructor(new Class[0]);
262        assertNull("Incorrect constructor returned", c.newInstance().cValue());
263        c = TestClass.class.getDeclaredConstructor(Object.class);
264    }
265
266    /**
267     * @tests java.lang.Class#getDeclaredConstructors()
268     */
269    public void test_getDeclaredConstructors() throws Exception {
270        Constructor[] c = TestClass.class.getDeclaredConstructors();
271        assertEquals("Incorrect number of constructors returned", 2, c.length);
272    }
273
274    /**
275     * @tests java.lang.Class#getDeclaredField(java.lang.String)
276     */
277    public void test_getDeclaredFieldLjava_lang_String() throws Exception {
278        Field f = TestClass.class.getDeclaredField("pubField");
279        assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
280    }
281
282    /**
283     * @tests java.lang.Class#getDeclaredFields()
284     */
285    public void test_getDeclaredFields() throws Exception {
286        Field[] f = TestClass.class.getDeclaredFields();
287        assertEquals("Returned incorrect number of fields", 4, f.length);
288        f = SubTestClass.class.getDeclaredFields();
289        // Declared fields do not include inherited
290        assertEquals("Returned incorrect number of fields", 0, f.length);
291    }
292
293    /**
294     * @tests java.lang.Class#getDeclaredMethod(java.lang.String,
295     *        java.lang.Class[])
296     */
297    public void test_getDeclaredMethodLjava_lang_String$Ljava_lang_Class() throws Exception {
298        Method m = TestClass.class.getDeclaredMethod("pubMethod", new Class[0]);
299        assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
300                .intValue());
301        m = TestClass.class.getDeclaredMethod("privMethod", new Class[0]);
302    }
303
304    /**
305     * @tests java.lang.Class#getDeclaredMethods()
306     */
307    public void test_getDeclaredMethods() throws Exception {
308        Method[] m = TestClass.class.getDeclaredMethods();
309        assertEquals("Returned incorrect number of methods", 3, m.length);
310        m = SubTestClass.class.getDeclaredMethods();
311        assertEquals("Returned incorrect number of methods", 0, m.length);
312    }
313
314    /**
315     * @tests java.lang.Class#getDeclaringClass()
316     */
317    public void test_getDeclaringClass() {
318        assertEquals(ClassTest.class, TestClass.class.getDeclaringClass());
319    }
320
321    /**
322     * @tests java.lang.Class#getField(java.lang.String)
323     */
324    public void test_getFieldLjava_lang_String() throws Exception {
325        Field f = TestClass.class.getField("pubField");
326        assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
327        try {
328            f = TestClass.class.getField("privField");
329            fail("Private field access failed to throw exception");
330        } catch (NoSuchFieldException e) {
331            // Correct
332        }
333    }
334
335    /**
336     * @tests java.lang.Class#getFields()
337     */
338    public void test_getFields() throws Exception {
339        Field[] f = TestClass.class.getFields();
340        assertEquals("Incorrect number of fields", 2, f.length);
341        f = SubTestClass.class.getFields();
342        // Check inheritance of pub fields
343        assertEquals("Incorrect number of fields", 2, f.length);
344    }
345
346    /**
347     * @tests java.lang.Class#getInterfaces()
348     */
349    public void test_getInterfaces() {
350        Class[] interfaces;
351        List<?> interfaceList;
352        interfaces = Object.class.getInterfaces();
353        assertEquals("Incorrect interface list for Object", 0, interfaces.length);
354        interfaceList = Arrays.asList(Vector.class.getInterfaces());
355        assertTrue("Incorrect interface list for Vector", interfaceList
356                .contains(Cloneable.class)
357                && interfaceList.contains(Serializable.class)
358                && interfaceList.contains(List.class));
359    }
360
361    /**
362     * @tests java.lang.Class#getMethod(java.lang.String, java.lang.Class[])
363     */
364    public void test_getMethodLjava_lang_String$Ljava_lang_Class() throws Exception {
365        Method m = TestClass.class.getMethod("pubMethod", new Class[0]);
366        assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
367                .intValue());
368        try {
369            m = TestClass.class.getMethod("privMethod", new Class[0]);
370            fail("Failed to throw exception accessing private method");
371        } catch (NoSuchMethodException e) {
372            // Correct
373            return;
374        }
375    }
376
377    /**
378     * @tests java.lang.Class#getMethods()
379     */
380    public void test_getMethods() throws Exception {
381        Method[] m = TestClass.class.getMethods();
382        assertEquals("Returned incorrect number of methods",
383                     2 + Object.class.getMethods().length, m.length);
384        m = SubTestClass.class.getMethods();
385        assertEquals("Returned incorrect number of sub-class methods",
386                     2 + Object.class.getMethods().length, m.length);
387        // Number of inherited methods
388    }
389
390    private static final class PrivateClass {
391    }
392    /**
393     * @tests java.lang.Class#getModifiers()
394     */
395    public void test_getModifiers() {
396        int dcm = PrivateClass.class.getModifiers();
397        assertFalse("default class is public", Modifier.isPublic(dcm));
398        assertFalse("default class is protected", Modifier.isProtected(dcm));
399        assertTrue("default class is not private", Modifier.isPrivate(dcm));
400
401        int ocm = Object.class.getModifiers();
402        assertTrue("public class is not public", Modifier.isPublic(ocm));
403        assertFalse("public class is protected", Modifier.isProtected(ocm));
404        assertFalse("public class is private", Modifier.isPrivate(ocm));
405    }
406
407    /**
408     * @tests java.lang.Class#getName()
409     */
410    public void test_getName() throws Exception {
411        String className = Class.forName("java.lang.Object").getName();
412        assertNotNull(className);
413
414        assertEquals("Class getName printed wrong value", "java.lang.Object", className);
415        assertEquals("Class getName printed wrong value", "int", int.class.getName());
416        className = Class.forName("[I").getName();
417        assertNotNull(className);
418        assertEquals("Class getName printed wrong value", "[I", className);
419
420        className = Class.forName("[Ljava.lang.Object;").getName();
421        assertNotNull(className);
422
423        assertEquals("Class getName printed wrong value", "[Ljava.lang.Object;", className);
424    }
425
426    /**
427     * @tests java.lang.Class#getResource(java.lang.String)
428     */
429    public void test_getResourceLjava_lang_String() {
430        final String name = "/org/apache/harmony/luni/tests/test_resource.txt";
431        URL res = getClass().getResource(name);
432        assertNotNull(res);
433    }
434
435    /**
436     * @tests java.lang.Class#getResourceAsStream(java.lang.String)
437     */
438    public void test_getResourceAsStreamLjava_lang_String() throws Exception {
439        final String name = "/org/apache/harmony/luni/tests/test_resource.txt";
440        assertNotNull("the file " + name + " can not be found in this directory", getClass()
441                .getResourceAsStream(name));
442
443        final String nameBadURI = "org/apache/harmony/luni/tests/test_resource.txt";
444        assertNull("the file " + nameBadURI + " should not be found in this directory",
445                getClass().getResourceAsStream(nameBadURI));
446
447        InputStream str = Object.class.getResourceAsStream("Class.class");
448        assertNotNull("java.lang.Object couldn't find its class with getResource...", str);
449
450        assertTrue("Cannot read single byte", str.read() != -1);
451        assertEquals("Cannot read multiple bytes", 5, str.read(new byte[5]));
452        str.close();
453
454        InputStream str2 = getClass().getResourceAsStream("ClassTest.class");
455        assertNotNull("Can't find resource", str2);
456        assertTrue("Cannot read single byte", str2.read() != -1);
457        assertEquals("Cannot read multiple bytes", 5, str2.read(new byte[5]));
458        str2.close();
459    }
460
461    /**
462     * @tests java.lang.Class#getSuperclass()
463     */
464    public void test_getSuperclass() {
465        assertNull("Object has a superclass???", Object.class.getSuperclass());
466        assertSame("Normal class has bogus superclass", InputStream.class,
467                FileInputStream.class.getSuperclass());
468        assertSame("Array class has bogus superclass", Object.class, FileInputStream[].class
469                .getSuperclass());
470        assertNull("Base class has a superclass", int.class.getSuperclass());
471        assertNull("Interface class has a superclass", Cloneable.class.getSuperclass());
472    }
473
474    /**
475     * @tests java.lang.Class#isArray()
476     */
477    public void test_isArray() throws ClassNotFoundException {
478        assertTrue("Non-array type claims to be.", !int.class.isArray());
479        Class<?> clazz = null;
480        clazz = Class.forName("[I");
481        assertTrue("int Array type claims not to be.", clazz.isArray());
482
483        clazz = Class.forName("[Ljava.lang.Object;");
484        assertTrue("Object Array type claims not to be.", clazz.isArray());
485
486        clazz = Class.forName("java.lang.Object");
487        assertTrue("Non-array Object type claims to be.", !clazz.isArray());
488    }
489
490    /**
491     * @tests java.lang.Class#isAssignableFrom(java.lang.Class)
492     */
493    public void test_isAssignableFromLjava_lang_Class() {
494        Class<?> clazz1 = null;
495        Class<?> clazz2 = null;
496
497        clazz1 = Object.class;
498        clazz2 = Class.class;
499        assertTrue("returned false for superclass", clazz1.isAssignableFrom(clazz2));
500
501        clazz1 = TestClass.class;
502        assertTrue("returned false for same class", clazz1.isAssignableFrom(clazz1));
503
504        clazz1 = Runnable.class;
505        clazz2 = Thread.class;
506        assertTrue("returned false for implemented interface", clazz1.isAssignableFrom(clazz2));
507    }
508
509    /**
510     * @tests java.lang.Class#isInterface()
511     */
512    public void test_isInterface() throws ClassNotFoundException {
513        assertTrue("Prim type claims to be interface.", !int.class.isInterface());
514        Class<?> clazz = null;
515        clazz = Class.forName("[I");
516        assertTrue("Prim Array type claims to be interface.", !clazz.isInterface());
517
518        clazz = Class.forName("java.lang.Runnable");
519        assertTrue("Interface type claims not to be interface.", clazz.isInterface());
520        clazz = Class.forName("java.lang.Object");
521        assertTrue("Object type claims to be interface.", !clazz.isInterface());
522
523        clazz = Class.forName("[Ljava.lang.Object;");
524        assertTrue("Array type claims to be interface.", !clazz.isInterface());
525    }
526
527    /**
528     * @tests java.lang.Class#isPrimitive()
529     */
530    public void test_isPrimitive() {
531        assertFalse("Interface type claims to be primitive.", Runnable.class.isPrimitive());
532        assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
533        assertFalse("Prim Array type claims to be primitive.", int[].class.isPrimitive());
534        assertFalse("Array type claims to be primitive.", Object[].class.isPrimitive());
535        assertTrue("Prim type claims not to be primitive.", int.class.isPrimitive());
536        assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
537    }
538
539    /**
540     * @tests java.lang.Class#newInstance()
541     */
542    public void test_newInstance() throws Exception {
543        Class<?> clazz = null;
544        clazz = Class.forName("java.lang.Object");
545        assertNotNull("new object instance was null", clazz.newInstance());
546
547        clazz = Class.forName("java.lang.Throwable");
548        assertSame("new Throwable instance was not a throwable",
549                   clazz, clazz.newInstance().getClass());
550
551        clazz = Class.forName("java.lang.Integer");
552        try {
553            clazz.newInstance();
554            fail("Exception for instantiating a newInstance with no default constructor is not thrown");
555        } catch (InstantiationException e) {
556            // expected
557        }
558    }
559
560    /**
561     * @tests java.lang.Class#toString()
562     */
563    public void test_toString() throws ClassNotFoundException {
564        assertEquals("Class toString printed wrong value",
565                     "int", int.class.toString());
566        Class<?> clazz = null;
567        clazz = Class.forName("[I");
568        assertEquals("Class toString printed wrong value",
569                     "class [I", clazz.toString());
570
571        clazz = Class.forName("java.lang.Object");
572        assertEquals("Class toString printed wrong value",
573                     "class java.lang.Object", clazz.toString());
574
575        clazz = Class.forName("[Ljava.lang.Object;");
576        assertEquals("Class toString printed wrong value",
577                     "class [Ljava.lang.Object;", clazz.toString());
578    }
579
580
581    // Regression Test for JIRA-2047
582	public void test_getResourceAsStream_withSharpChar() throws Exception{
583		InputStream in = getClass().getResourceAsStream("/"+FILENAME);
584		assertNotNull(in);
585		in.close();
586
587        in = getClass().getResourceAsStream(FILENAME);
588        assertNull(in);
589
590		in = this.getClass().getClassLoader().getResourceAsStream(
591				FILENAME);
592		assertNotNull(in);
593		in.close();
594	}
595
596        /*
597         * Regression test for HARMONY-2644:
598         * Load system and non-system array classes via Class.forName()
599         */
600        public void test_forName_arrays() throws Exception {
601            Class c1 = getClass();
602            String s = c1.getName();
603            Class a1 = Class.forName("[L" + s + ";");
604            Class a2 = Class.forName("[[L" + s + ";");
605            assertSame(c1, a1.getComponentType());
606            assertSame(a1, a2.getComponentType());
607            Class l4 = Class.forName("[[[[[J");
608            assertSame(long[][][][][].class, l4);
609
610            try{
611                System.out.println(Class.forName("[;"));
612                fail("1");
613            } catch (ClassNotFoundException ok) {}
614            try{
615                System.out.println(Class.forName("[["));
616                fail("2");
617            } catch (ClassNotFoundException ok) {}
618            try{
619                System.out.println(Class.forName("[L"));
620                fail("3");
621            } catch (ClassNotFoundException ok) {}
622            try{
623                System.out.println(Class.forName("[L;"));
624                fail("4");
625            } catch (ClassNotFoundException ok) {}
626            try{
627                System.out.println(Class.forName(";"));
628                fail("5");
629            } catch (ClassNotFoundException ok) {}
630            try{
631                System.out.println(Class.forName(""));
632                fail("6");
633            } catch (ClassNotFoundException ok) {}
634        }
635}
636