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