ClassLoaderTest.java revision 89c1feb0a69a7707b271086e749975b3f7acacf7
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 dalvik.annotation.TestInfo; 21import dalvik.annotation.TestLevel; 22import dalvik.annotation.TestTarget; 23import dalvik.annotation.TestTargetClass; 24 25import junit.framework.TestCase; 26 27import java.io.File; 28import java.io.InputStream; 29import java.security.CodeSource; 30import java.security.Permission; 31import java.security.PermissionCollection; 32import java.security.Policy; 33import java.security.ProtectionDomain; 34import java.security.SecurityPermission; 35 36@TestTargetClass(ClassLoader.class) 37public class ClassLoaderTest extends TestCase { 38 39 public static volatile int flag; 40 41 /** 42 * Tests that Classloader.defineClass() assigns appropriate 43 * default domains to the defined classes. 44 */ 45 @TestInfo( 46 level = TestLevel.PARTIAL, 47 purpose = "Verifies only positive functionality.", 48 targets = { 49 @TestTarget( 50 methodName = "defineClass", 51 methodArgs = {java.lang.String.class, byte[].class, int.class, int.class} 52 ) 53 }) 54 public void _test_defineClass_defaultDomain() throws Exception { 55 // Regression for HARMONY-765 56 DynamicPolicy plc = new DynamicPolicy(); 57 Policy back = Policy.getPolicy(); 58 try { 59 Policy.setPolicy(plc); 60 61 Class<?> a = new Ldr().define(); 62 63 Permission p = new SecurityPermission("abc"); 64 assertFalse("impossible! misconfiguration?", a.getProtectionDomain().implies(p)); 65 66 plc.pc = p.newPermissionCollection(); 67 plc.pc.add(p); 68 assertTrue("default domain is not dynamic", a.getProtectionDomain().implies(p)); 69 } finally { 70 Policy.setPolicy(back); 71 } 72 } 73 74 static class SyncTestClassLoader extends ClassLoader { 75 Object lock; 76 volatile int numFindClassCalled; 77 78 SyncTestClassLoader(Object o) { 79 this.lock = o; 80 numFindClassCalled = 0; 81 } 82 83 /* 84 * Byte array of bytecode equivalent to the following source code: 85 * public class TestClass { 86 * } 87 */ 88 private byte[] classData = new byte[] { 89 -54, -2, -70, -66, 0, 0, 0, 49, 0, 13, 90 10, 0, 3, 0, 10, 7, 0, 11, 7, 0, 91 12, 1, 0, 6, 60, 105, 110, 105, 116, 62, 92 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 93 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 94 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 95 101, 1, 0, 10, 83, 111, 117, 114, 99, 101, 96 70, 105, 108, 101, 1, 0, 14, 84, 101, 115, 97 116, 67, 108, 97, 115, 115, 46, 106, 97, 118, 98 97, 12, 0, 4, 0, 5, 1, 0, 9, 84, 99 101, 115, 116, 67, 108, 97, 115, 115, 1, 0, 100 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 101 47, 79, 98, 106, 101, 99, 116, 0, 33, 0, 102 2, 0, 3, 0, 0, 0, 0, 0, 1, 0, 103 1, 0, 4, 0, 5, 0, 1, 0, 6, 0, 104 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 105 5, 42, -73, 0, 1, -79, 0, 0, 0, 1, 106 0, 7, 0, 0, 0, 6, 0, 1, 0, 0, 107 0, 1, 0, 1, 0, 8, 0, 0, 0, 2, 108 0, 9 }; 109 110 protected Class findClass(String name) throws ClassNotFoundException { 111 try { 112 while (flag != 2) { 113 synchronized (lock) { 114 lock.wait(); 115 } 116 } 117 } catch (InterruptedException ie) {} 118 119 if (name.equals("TestClass")) { 120 numFindClassCalled++; 121 return defineClass(null, classData, 0, classData.length); 122 } else { 123 throw new ClassNotFoundException("Class " + name + " not found."); 124 } 125 } 126 } 127 128 static class SyncLoadTestThread extends Thread { 129 volatile boolean started; 130 ClassLoader cl; 131 Class cls; 132 133 SyncLoadTestThread(ClassLoader cl) { 134 this.cl = cl; 135 } 136 137 public void run() { 138 try { 139 started = true; 140 cls = Class.forName("TestClass", false, cl); 141 } catch (Exception ex) { 142 ex.printStackTrace(); 143 } 144 } 145 } 146 147 /** 148 * Regression test for HARMONY-1939: 149 * 2 threads simultaneously run Class.forName() method for the same classname 150 * and the same classloader. It is expected that both threads succeed but 151 * class must be defined just once. 152 */ 153 @TestInfo( 154 level = TestLevel.PARTIAL, 155 purpose = "Regression test.", 156 targets = { 157 @TestTarget( 158 methodName = "loadClass", 159 methodArgs = {java.lang.String.class} 160 ) 161 }) 162 public void _test_loadClass_concurrentLoad() throws Exception 163 { 164 Object lock = new Object(); 165 SyncTestClassLoader cl = new SyncTestClassLoader(lock); 166 SyncLoadTestThread tt1 = new SyncLoadTestThread(cl); 167 SyncLoadTestThread tt2 = new SyncLoadTestThread(cl); 168 flag = 1; 169 tt1.start(); 170 tt2.start(); 171 172 while (!tt1.started && !tt2.started) { 173 Thread.sleep(100); 174 } 175 176 flag = 2; 177 synchronized (lock) { 178 lock.notifyAll(); 179 } 180 tt1.join(); 181 tt2.join(); 182 183 assertSame("Bad or redefined class", tt1.cls, tt2.cls); 184 assertEquals("Both threads tried to define class", 1, cl.numFindClassCalled); 185 } 186 187 /** 188 * @tests java.lang.ClassLoader#getResource(java.lang.String) 189 */ 190 @TestInfo( 191 level = TestLevel.PARTIAL, 192 purpose = "Verifies only positive case.", 193 targets = { 194 @TestTarget( 195 methodName = "getResource", 196 methodArgs = {java.lang.String.class} 197 ) 198 }) 199 public void test_getResourceLjava_lang_String() { 200 // Test for method java.net.URL 201 // java.lang.ClassLoader.getResource(java.lang.String) 202 java.net.URL u = ClassLoader.getSystemClassLoader().getResource("hyts_Foo.c"); 203 assertNotNull("Unable to find resource", u); 204 java.io.InputStream is = null; 205 try { 206 is = u.openStream(); 207 assertNotNull("Resource returned is invalid", is); 208 is.close(); 209 } catch (java.io.IOException e) { 210 fail("IOException getting stream for resource : " + e.getMessage()); 211 } 212 } 213 214 /** 215 * @tests java.lang.ClassLoader#getResourceAsStream(java.lang.String) 216 */ 217 @TestInfo( 218 level = TestLevel.PARTIAL, 219 purpose = "Verifies only positive case.", 220 targets = { 221 @TestTarget( 222 methodName = "getResourceAsStream", 223 methodArgs = {java.lang.String.class} 224 ) 225 }) 226 public void test_getResourceAsStreamLjava_lang_String() { 227 // Test for method java.io.InputStream 228 // java.lang.ClassLoader.getResourceAsStream(java.lang.String) 229 // Need better test... 230 231 java.io.InputStream is = null; 232 assertNotNull("Failed to find resource: hyts_Foo.c", (is = ClassLoader 233 .getSystemClassLoader().getResourceAsStream("hyts_Foo.c"))); 234 try { 235 is.close(); 236 } catch (java.io.IOException e) { 237 fail("Exception during getResourceAsStream: " + e.toString()); 238 } 239 } 240 241 /** 242 * @tests java.lang.ClassLoader#getSystemClassLoader() 243 */ 244 @TestInfo( 245 level = TestLevel.COMPLETE, 246 purpose = "", 247 targets = { 248 @TestTarget( 249 methodName = "getSystemClassLoader", 250 methodArgs = {} 251 ) 252 }) 253 public void test_getSystemClassLoader() { 254 // Test for method java.lang.ClassLoader 255 // java.lang.ClassLoader.getSystemClassLoader() 256 ClassLoader cl = ClassLoader.getSystemClassLoader(); 257 java.io.InputStream is = cl.getResourceAsStream("hyts_Foo.c"); 258 assertNotNull("Failed to find resource from system classpath", is); 259 try { 260 is.close(); 261 } catch (java.io.IOException e) { 262 } 263 264 } 265 266 /** 267 * @tests java.lang.ClassLoader#getSystemResource(java.lang.String) 268 */ 269 @TestInfo( 270 level = TestLevel.COMPLETE, 271 purpose = "Doesn't verify functionality.", 272 targets = { 273 @TestTarget( 274 methodName = "getSystemResource", 275 methodArgs = {java.lang.String.class} 276 ) 277 }) 278 public void test_getSystemResourceLjava_lang_String() { 279 // Test for method java.net.URL 280 // java.lang.ClassLoader.getSystemResource(java.lang.String) 281 // Need better test... 282 assertNotNull("Failed to find resource: hyts_Foo.c", ClassLoader 283 .getSystemResource("hyts_Foo.c")); 284 } 285 286 287 //Regression Test for JIRA-2047 288 @TestInfo( 289 level = TestLevel.PARTIAL, 290 purpose = "Verifies only positive case.", 291 targets = { 292 @TestTarget( 293 methodName = "getResourceAsStream", 294 methodArgs = {java.lang.String.class} 295 ) 296 }) 297 public void _test_getResourceAsStream_withSharpChar() throws Exception { 298 /* 299 * The Harmony resource could not be found anywhere, so we take 300 * our own. 301 */ 302 InputStream in = this.getClass().getClassLoader().getResourceAsStream( 303 "test#.properties" /* ClassTest.FILENAME */); 304 assertNotNull(in); 305 in.close(); 306 } 307} 308 309class DynamicPolicy extends Policy { 310 311 public PermissionCollection pc; 312 313 @Override 314 public PermissionCollection getPermissions(ProtectionDomain pd) { 315 return pc; 316 } 317 318 @Override 319 public PermissionCollection getPermissions(CodeSource codesource) { 320 return pc; 321 } 322 323 @Override 324 public void refresh() { 325 } 326} 327 328class A { 329} 330 331class Ldr extends ClassLoader { 332 @SuppressWarnings("deprecation") 333 public Class<?> define() throws Exception { 334 Package p = getClass().getPackage(); 335 String path = p == null ? "" : p.getName().replace('.', File.separatorChar) 336 + File.separator; 337 InputStream is = getResourceAsStream(path + "A.class"); 338 byte[] buf = new byte[512]; 339 int len = is.read(buf); 340 return defineClass("org.apache.harmony.luni.tests.java.lang.A", buf, 0, len); 341 } 342} 343