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 
18 package org.apache.harmony.tests.java.lang;
19 
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.Serializable;
24 import java.lang.annotation.Retention;
25 import java.lang.annotation.RetentionPolicy;
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.Field;
28 import java.lang.reflect.Method;
29 import java.lang.reflect.Modifier;
30 import java.net.URL;
31 import java.security.AccessController;
32 import java.security.BasicPermission;
33 import java.security.DomainCombiner;
34 import java.security.Permission;
35 import java.security.ProtectionDomain;
36 import java.security.Security;
37 import java.util.Arrays;
38 import java.util.List;
39 import java.util.TreeMap;
40 import java.util.Vector;
41 import java.util.function.Function;
42 
43 public class ClassTest extends junit.framework.TestCase {
44 
45     // Relative resource paths.
46     private static final String SHARP_RESOURCE_RELATIVE_NAME = "test#.properties";
47     private static final String QUERY_RESOURCE_RELATIVE_NAME = "test?.properties";
48     private static final String RESOURCE_RELATIVE_NAME = "test.properties";
49 
50     // Absolute resource paths.
51     private static final String ABS_PATH =
52             ClassTest.class.getPackage().getName().replace('.', '/');
53     public static final String SHARP_RESOURCE_ABS_NAME =
54             ABS_PATH + "/" + SHARP_RESOURCE_RELATIVE_NAME;
55     public static final String QUERY_RESOURCE_ABS_NAME =
56             ABS_PATH + "/" + QUERY_RESOURCE_RELATIVE_NAME;
57     public static final String RESOURCE_ABS_NAME = ABS_PATH + "/" + RESOURCE_RELATIVE_NAME;
58 
59     public static class TestClass {
60         @SuppressWarnings("unused")
61         private int privField = 1;
62 
63         public int pubField = 2;
64 
65         private Object cValue = null;
66 
67         public Object ack = new Object();
68 
69         @SuppressWarnings("unused")
privMethod()70         private int privMethod() {
71             return 1;
72         }
73 
pubMethod()74         public int pubMethod() {
75             return 2;
76         }
77 
cValue()78         public Object cValue() {
79             return cValue;
80         }
81 
TestClass()82         public TestClass() {
83         }
84 
85         @SuppressWarnings("unused")
TestClass(Object o)86         private TestClass(Object o) {
87         }
88     }
89 
90     public static class SubTestClass extends TestClass {
91     }
92 
93     /**
94      * java.lang.Class#forName(java.lang.String)
95      */
test_forNameLjava_lang_String()96     public void test_forNameLjava_lang_String() throws Exception {
97         assertSame("Class for name failed for java.lang.Object",
98                 Object.class, Class.forName("java.lang.Object"));
99         assertSame("Class for name failed for [[Ljava.lang.Object;",
100                 Object[][].class, Class.forName("[[Ljava.lang.Object;"));
101 
102         assertSame("Class for name failed for [I",
103                 int[].class, Class.forName("[I"));
104 
105         try {
106             Class.forName("int");
107             fail();
108         } catch (ClassNotFoundException e) {
109         }
110 
111         try {
112             Class.forName("byte");
113             fail();
114         } catch (ClassNotFoundException e) {
115         }
116         try {
117             Class.forName("char");
118             fail();
119         } catch (ClassNotFoundException e) {
120         }
121 
122         try {
123             Class.forName("void");
124             fail();
125         } catch (ClassNotFoundException e) {
126         }
127 
128         try {
129             Class.forName("short");
130             fail();
131         } catch (ClassNotFoundException e) {
132         }
133         try {
134             Class.forName("long");
135             fail();
136         } catch (ClassNotFoundException e) {
137         }
138 
139         try {
140             Class.forName("boolean");
141             fail();
142         } catch (ClassNotFoundException e) {
143         }
144         try {
145             Class.forName("float");
146             fail();
147         } catch (ClassNotFoundException e) {
148         }
149         try {
150             Class.forName("double");
151             fail();
152         } catch (ClassNotFoundException e) {
153         }
154 
155         //regression test for JIRA 2162
156         try {
157             Class.forName("%");
158             fail("should throw ClassNotFoundException.");
159         } catch (ClassNotFoundException e) {
160         }
161 
162         //Regression Test for HARMONY-3332
163         String securityProviderClassName;
164         int count = 1;
165         while ((securityProviderClassName = Security
166                 .getProperty("security.provider." + count++)) != null) {
167             Class.forName(securityProviderClassName);
168         }
169     }
170 
171     /**
172      * java.lang.Class#getClasses()
173      */
test_getClasses()174     public void test_getClasses() {
175         assertEquals("Incorrect class array returned",
176                 2, ClassTest.class.getClasses().length);
177     }
178 
179     /**
180      * java.lang.Class#getClasses()
181      */
test_getClasses_subtest0()182     public void test_getClasses_subtest0() {
183         final Permission privCheckPermission = new BasicPermission("Privilege check") {
184             private static final long serialVersionUID = 1L;
185         };
186 
187         class MyCombiner implements DomainCombiner {
188             boolean combine;
189 
190             public ProtectionDomain[] combine(ProtectionDomain[] executionDomains,
191                     ProtectionDomain[] parentDomains) {
192                 combine = true;
193                 return new ProtectionDomain[0];
194             }
195 
196             private boolean recurring = false;
197 
198             public boolean isPriviledged() {
199                 if (recurring) {
200                     return true;
201                 }
202                 try {
203                     recurring = true;
204                     combine = false;
205                     try {
206                         AccessController.checkPermission(privCheckPermission);
207                     } catch (SecurityException e) {
208                     }
209                     return !combine;
210                 } finally {
211                     recurring = false;
212                 }
213             }
214         }
215     }
216 
217     /**
218      * java.lang.Class#getComponentType()
219      */
test_getComponentType()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      * java.lang.Class#getConstructor(java.lang.Class[])
230      */
test_getConstructor$Ljava_lang_Class()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      * java.lang.Class#getConstructors()
244      */
test_getConstructors()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      * java.lang.Class#getDeclaredClasses()
252      */
test_getDeclaredClasses()253     public void test_getDeclaredClasses() {
254         assertEquals("Incorrect class array returned", 2, ClassTest.class.getClasses().length);
255     }
256 
257     /**
258      * java.lang.Class#getDeclaredConstructor(java.lang.Class[])
259      */
test_getDeclaredConstructor$Ljava_lang_Class()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      * java.lang.Class#getDeclaredConstructors()
268      */
test_getDeclaredConstructors()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      * java.lang.Class#getDeclaredField(java.lang.String)
276      */
test_getDeclaredFieldLjava_lang_String()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      * java.lang.Class#getDeclaredFields()
284      */
test_getDeclaredFields()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      * java.lang.Class#getDeclaredMethod(java.lang.String,
295      *java.lang.Class[])
296      */
test_getDeclaredMethodLjava_lang_String$Ljava_lang_Class()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      * java.lang.Class#getDeclaredMethods()
306      */
test_getDeclaredMethods()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      * java.lang.Class#getDeclaringClass()
316      */
test_getDeclaringClass()317     public void test_getDeclaringClass() {
318         assertEquals(ClassTest.class, TestClass.class.getDeclaringClass());
319     }
320 
321     /**
322      * java.lang.Class#getField(java.lang.String)
323      */
test_getFieldLjava_lang_String()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      * java.lang.Class#getFields()
337      */
test_getFields()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      * java.lang.Class#getInterfaces()
348      */
test_getInterfaces()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      * java.lang.Class#getMethod(java.lang.String, java.lang.Class[])
363      */
test_getMethodLjava_lang_String$Ljava_lang_Class()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      * java.lang.Class#getMethods()
379      */
test_getMethods()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     /**
394      * java.lang.Class#getModifiers()
395      */
test_getModifiers()396     public void test_getModifiers() {
397         int dcm = PrivateClass.class.getModifiers();
398         assertFalse("default class is public", Modifier.isPublic(dcm));
399         assertFalse("default class is protected", Modifier.isProtected(dcm));
400         assertTrue("default class is not private", Modifier.isPrivate(dcm));
401 
402         int ocm = Object.class.getModifiers();
403         assertTrue("public class is not public", Modifier.isPublic(ocm));
404         assertFalse("public class is protected", Modifier.isProtected(ocm));
405         assertFalse("public class is private", Modifier.isPrivate(ocm));
406     }
407 
408     /**
409      * java.lang.Class#getName()
410      */
test_getName()411     public void test_getName() throws Exception {
412         String className = Class.forName("java.lang.Object").getName();
413         assertNotNull(className);
414 
415         assertEquals("Class getName printed wrong value", "java.lang.Object", className);
416         assertEquals("Class getName printed wrong value", "int", int.class.getName());
417         className = Class.forName("[I").getName();
418         assertNotNull(className);
419         assertEquals("Class getName printed wrong value", "[I", className);
420 
421         className = Class.forName("[Ljava.lang.Object;").getName();
422         assertNotNull(className);
423 
424         assertEquals("Class getName printed wrong value", "[Ljava.lang.Object;", className);
425     }
426 
427     /**
428      * java.lang.Class#getResource(java.lang.String)
429      */
test_getResourceLjava_lang_String()430     public void test_getResourceLjava_lang_String() {
431         final String name = "/resources/test_resource.txt";
432         URL res = getClass().getResource(name);
433         assertNotNull(res);
434     }
435 
436     /**
437      * java.lang.Class#getResourceAsStream(java.lang.String)
438      */
test_getResourceAsStreamLjava_lang_String()439     public void test_getResourceAsStreamLjava_lang_String() throws Exception {
440         final String name = "/resources/test_resource.txt";
441         InputStream str2 = getClass().getResourceAsStream(name);
442         assertNotNull("the file " + name + " can not be found in this directory", str2);
443 
444         final String nameBadURI = "org/apache/harmony/luni/tests/test_resource.txt";
445         assertNull("the file " + nameBadURI + " should not be found in this directory",
446                 getClass().getResourceAsStream(nameBadURI));
447 
448         assertTrue("Cannot read single byte", str2.read() != -1);
449         assertEquals("Cannot read multiple bytes", 5, str2.read(new byte[5]));
450         str2.close();
451     }
452 
453     /**
454      * java.lang.Class#getSuperclass()
455      */
test_getSuperclass()456     public void test_getSuperclass() {
457         assertNull("Object has a superclass???", Object.class.getSuperclass());
458         assertSame("Normal class has bogus superclass", InputStream.class,
459                 FileInputStream.class.getSuperclass());
460         assertSame("Array class has bogus superclass", Object.class, FileInputStream[].class
461                 .getSuperclass());
462         assertNull("Base class has a superclass", int.class.getSuperclass());
463         assertNull("Interface class has a superclass", Cloneable.class.getSuperclass());
464     }
465 
466     /**
467      * java.lang.Class#isArray()
468      */
test_isArray()469     public void test_isArray() throws ClassNotFoundException {
470         assertTrue("Non-array type claims to be.", !int.class.isArray());
471         Class<?> clazz = null;
472         clazz = Class.forName("[I");
473         assertTrue("int Array type claims not to be.", clazz.isArray());
474 
475         clazz = Class.forName("[Ljava.lang.Object;");
476         assertTrue("Object Array type claims not to be.", clazz.isArray());
477 
478         clazz = Class.forName("java.lang.Object");
479         assertTrue("Non-array Object type claims to be.", !clazz.isArray());
480     }
481 
482     /**
483      * java.lang.Class#isAssignableFrom(java.lang.Class)
484      */
test_isAssignableFromLjava_lang_Class()485     public void test_isAssignableFromLjava_lang_Class() {
486         Class<?> clazz1 = null;
487         Class<?> clazz2 = null;
488 
489         clazz1 = Object.class;
490         clazz2 = Class.class;
491         assertTrue("returned false for superclass", clazz1.isAssignableFrom(clazz2));
492 
493         clazz1 = TestClass.class;
494         assertTrue("returned false for same class", clazz1.isAssignableFrom(clazz1));
495 
496         clazz1 = Runnable.class;
497         clazz2 = Thread.class;
498         assertTrue("returned false for implemented interface", clazz1.isAssignableFrom(clazz2));
499     }
500 
501     /**
502      * java.lang.Class#isInterface()
503      */
test_isInterface()504     public void test_isInterface() throws ClassNotFoundException {
505         assertTrue("Prim type claims to be interface.", !int.class.isInterface());
506         Class<?> clazz = null;
507         clazz = Class.forName("[I");
508         assertTrue("Prim Array type claims to be interface.", !clazz.isInterface());
509 
510         clazz = Class.forName("java.lang.Runnable");
511         assertTrue("Interface type claims not to be interface.", clazz.isInterface());
512         clazz = Class.forName("java.lang.Object");
513         assertTrue("Object type claims to be interface.", !clazz.isInterface());
514 
515         clazz = Class.forName("[Ljava.lang.Object;");
516         assertTrue("Array type claims to be interface.", !clazz.isInterface());
517     }
518 
519     /**
520      * java.lang.Class#isPrimitive()
521      */
test_isPrimitive()522     public void test_isPrimitive() {
523         assertFalse("Interface type claims to be primitive.", Runnable.class.isPrimitive());
524         assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
525         assertFalse("Prim Array type claims to be primitive.", int[].class.isPrimitive());
526         assertFalse("Array type claims to be primitive.", Object[].class.isPrimitive());
527         assertTrue("Prim type claims not to be primitive.", int.class.isPrimitive());
528         assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
529     }
530 
531     /**
532      * java.lang.Class#newInstance()
533      */
test_newInstance()534     public void test_newInstance() throws Exception {
535         Class<?> clazz = null;
536         clazz = Class.forName("java.lang.Object");
537         assertNotNull("new object instance was null", clazz.newInstance());
538 
539         clazz = Class.forName("java.lang.Throwable");
540         assertSame("new Throwable instance was not a throwable",
541                 clazz, clazz.newInstance().getClass());
542 
543         clazz = Class.forName("java.lang.Integer");
544         try {
545             clazz.newInstance();
546             fail("Exception for instantiating a newInstance with no default constructor is not thrown");
547         } catch (InstantiationException e) {
548             // expected
549         }
550     }
551 
552     // Regression Test for JIRA-2047
test_getResourceAsStream_withSharpChar()553     public void test_getResourceAsStream_withSharpChar() throws Exception {
554         // Class.getResourceAsStream() requires a leading "/" for absolute paths.
555         assertNull(getClass().getResourceAsStream(SHARP_RESOURCE_ABS_NAME));
556         assertResourceExists("/" + SHARP_RESOURCE_ABS_NAME);
557         assertResourceExists(SHARP_RESOURCE_RELATIVE_NAME);
558 
559         InputStream in =
560                 this.getClass().getClassLoader().getResourceAsStream(SHARP_RESOURCE_ABS_NAME);
561         assertNotNull(in);
562         in.close();
563     }
564 
test_getResource_withSharpChar()565     public void test_getResource_withSharpChar() throws Exception {
566         // Class.getResourceAsStream() requires a leading "/" for absolute paths.
567         assertNull(getClass().getResource(SHARP_RESOURCE_ABS_NAME));
568         URL absoluteURL = getClass().getResource("/" + SHARP_RESOURCE_ABS_NAME);
569 
570         // Make sure the name has been encoded.
571         assertEquals(ABS_PATH + "/test%23.properties",
572                 absoluteURL.getFile().replaceAll("^.*!/", ""));
573 
574         // Make sure accessing it via an absolute and relative path produces the same result.
575         URL relativeURL = getClass().getResource(SHARP_RESOURCE_RELATIVE_NAME);
576         assertEquals(absoluteURL, relativeURL);
577     }
578 
test_getResourceAsStream_withQueryChar()579     public void test_getResourceAsStream_withQueryChar() throws Exception {
580         // Class.getResourceAsStream() requires a leading "/" for absolute paths.
581         assertNull(getClass().getResourceAsStream(QUERY_RESOURCE_ABS_NAME));
582         assertResourceExists("/" + QUERY_RESOURCE_ABS_NAME);
583         assertResourceExists(QUERY_RESOURCE_RELATIVE_NAME);
584 
585         InputStream in =
586                 this.getClass().getClassLoader().getResourceAsStream(QUERY_RESOURCE_ABS_NAME);
587         assertNotNull(in);
588         in.close();
589     }
590 
test_getResource_withQueryChar()591     public void test_getResource_withQueryChar() throws Exception {
592         // Class.getResourceAsStream() requires a leading "/" for absolute paths.
593         assertNull(getClass().getResource(QUERY_RESOURCE_ABS_NAME));
594         URL absoluteURL = getClass().getResource("/" + QUERY_RESOURCE_ABS_NAME);
595 
596         // Make sure the name has been encoded.
597         assertEquals(ABS_PATH + "/test%3f.properties",
598                 absoluteURL.getFile().replaceAll("^.*!/", ""));
599 
600         // Make sure accessing it via an absolute and relative path produces the same result.
601         URL relativeURL = getClass().getResource(QUERY_RESOURCE_RELATIVE_NAME);
602         assertEquals(absoluteURL, relativeURL);
603     }
604 
test_getResourceAsStream()605     public void test_getResourceAsStream() throws Exception {
606         // Class.getResourceAsStream() requires a leading "/" for absolute paths.
607         assertNull(getClass().getResourceAsStream(RESOURCE_ABS_NAME));
608         assertResourceExists("/" + RESOURCE_ABS_NAME);
609         assertResourceExists(RESOURCE_RELATIVE_NAME);
610 
611         InputStream in = this.getClass().getClassLoader().getResourceAsStream(RESOURCE_ABS_NAME);
612         assertNotNull(in);
613         in.close();
614     }
615 
assertResourceExists(String resourceName)616     private void assertResourceExists(String resourceName) throws IOException {
617         InputStream in = getClass().getResourceAsStream(resourceName);
618         assertNotNull(in);
619         in.close();
620     }
621 
622     /*
623     * Regression test for HARMONY-2644:
624     * Load system and non-system array classes via Class.forName()
625     */
test_forName_arrays()626     public void test_forName_arrays() throws Exception {
627         Class c1 = getClass();
628         String s = c1.getName();
629         Class a1 = Class.forName("[L" + s + ";");
630         Class a2 = Class.forName("[[L" + s + ";");
631         assertSame(c1, a1.getComponentType());
632         assertSame(a1, a2.getComponentType());
633         Class l4 = Class.forName("[[[[[J");
634         assertSame(long[][][][][].class, l4);
635 
636         try {
637             System.out.println(Class.forName("[;"));
638             fail("1");
639         } catch (ClassNotFoundException ok) {
640         }
641         try {
642             System.out.println(Class.forName("[["));
643             fail("2");
644         } catch (ClassNotFoundException ok) {
645         }
646         try {
647             System.out.println(Class.forName("[L"));
648             fail("3");
649         } catch (ClassNotFoundException ok) {
650         }
651         try {
652             System.out.println(Class.forName("[L;"));
653             fail("4");
654         } catch (ClassNotFoundException ok) {
655         }
656         try {
657             System.out.println(Class.forName(";"));
658             fail("5");
659         } catch (ClassNotFoundException ok) {
660         }
661         try {
662             System.out.println(Class.forName(""));
663             fail("6");
664         } catch (ClassNotFoundException ok) {
665         }
666     }
667 }
668