blob: ca4ae2807e85fcf06c1d3d6f7b3c07f8f23812e4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.luni.tests.java.lang;
import java.io.InputStream;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.SecurityPermission;
import junit.framework.TestCase;
public class ClassLoaderTest extends TestCase {
public static volatile int flag;
/**
* Tests that Classloader.defineClass() assigns appropriate
* default domains to the defined classes.
*/
public void test_defineClass_defaultDomain() throws Exception {
// Regression for HARMONY-765
DynamicPolicy plc = new DynamicPolicy();
Policy back = Policy.getPolicy();
try {
Policy.setPolicy(plc);
Class<?> a = new Ldr().define();
Permission p = new SecurityPermission("abc");
assertFalse("impossible! misconfiguration?", a.getProtectionDomain().implies(p));
plc.pc = p.newPermissionCollection();
plc.pc.add(p);
assertTrue("default domain is not dynamic", a.getProtectionDomain().implies(p));
} finally {
Policy.setPolicy(back);
}
}
static class SyncTestClassLoader extends ClassLoader {
Object lock;
volatile int numFindClassCalled;
SyncTestClassLoader(Object o) {
this.lock = o;
numFindClassCalled = 0;
}
/*
* Byte array of bytecode equivalent to the following source code:
* public class TestClass {
* }
*/
private byte[] classData = new byte[] {
-54, -2, -70, -66, 0, 0, 0, 49, 0, 13,
10, 0, 3, 0, 10, 7, 0, 11, 7, 0,
12, 1, 0, 6, 60, 105, 110, 105, 116, 62,
1, 0, 3, 40, 41, 86, 1, 0, 4, 67,
111, 100, 101, 1, 0, 15, 76, 105, 110, 101,
78, 117, 109, 98, 101, 114, 84, 97, 98, 108,
101, 1, 0, 10, 83, 111, 117, 114, 99, 101,
70, 105, 108, 101, 1, 0, 14, 84, 101, 115,
116, 67, 108, 97, 115, 115, 46, 106, 97, 118,
97, 12, 0, 4, 0, 5, 1, 0, 9, 84,
101, 115, 116, 67, 108, 97, 115, 115, 1, 0,
16, 106, 97, 118, 97, 47, 108, 97, 110, 103,
47, 79, 98, 106, 101, 99, 116, 0, 33, 0,
2, 0, 3, 0, 0, 0, 0, 0, 1, 0,
1, 0, 4, 0, 5, 0, 1, 0, 6, 0,
0, 0, 29, 0, 1, 0, 1, 0, 0, 0,
5, 42, -73, 0, 1, -79, 0, 0, 0, 1,
0, 7, 0, 0, 0, 6, 0, 1, 0, 0,
0, 1, 0, 1, 0, 8, 0, 0, 0, 2,
0, 9 };
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
while (flag != 2) {
synchronized (lock) {
lock.wait();
}
}
} catch (InterruptedException ie) {}
if (name.equals("TestClass")) {
numFindClassCalled++;
return defineClass(null, classData, 0, classData.length);
}
throw new ClassNotFoundException("Class " + name + " not found.");
}
}
static class SyncLoadTestThread extends Thread {
volatile boolean started;
ClassLoader cl;
Class<?> cls;
SyncLoadTestThread(ClassLoader cl) {
this.cl = cl;
}
@Override
public void run() {
try {
started = true;
cls = Class.forName("TestClass", false, cl);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* Regression test for HARMONY-1939:
* 2 threads simultaneously run Class.forName() method for the same classname
* and the same classloader. It is expected that both threads succeed but
* class must be defined just once.
*/
public void test_loadClass_concurrentLoad() throws Exception
{
Object lock = new Object();
SyncTestClassLoader cl = new SyncTestClassLoader(lock);
SyncLoadTestThread tt1 = new SyncLoadTestThread(cl);
SyncLoadTestThread tt2 = new SyncLoadTestThread(cl);
flag = 1;
tt1.start();
tt2.start();
while (!tt1.started && !tt2.started) {
Thread.sleep(100);
}
flag = 2;
synchronized (lock) {
lock.notifyAll();
}
tt1.join();
tt2.join();
assertSame("Bad or redefined class", tt1.cls, tt2.cls);
assertEquals("Both threads tried to define class", 1, cl.numFindClassCalled);
}
/**
* @tests java.lang.ClassLoader#getResource(java.lang.String)
*/
public void test_getResourceLjava_lang_String() {
// Test for method java.net.URL
// java.lang.ClassLoader.getResource(java.lang.String)
java.net.URL u = ClassLoader.getSystemClassLoader().getResource("hyts_Foo.c");
assertNotNull("Unable to find resource", u);
java.io.InputStream is = null;
try {
is = u.openStream();
assertNotNull("Resource returned is invalid", is);
is.close();
} catch (java.io.IOException e) {
fail("IOException getting stream for resource : " + e.getMessage());
}
}
/**
* @tests java.lang.ClassLoader#getResourceAsStream(java.lang.String)
*/
public void test_getResourceAsStreamLjava_lang_String() {
// Test for method java.io.InputStream
// java.lang.ClassLoader.getResourceAsStream(java.lang.String)
// Need better test...
java.io.InputStream is = null;
assertNotNull("Failed to find resource: hyts_Foo.c", (is = ClassLoader
.getSystemClassLoader().getResourceAsStream("hyts_Foo.c")));
try {
is.close();
} catch (java.io.IOException e) {
fail("Exception during getResourceAsStream: " + e.toString());
}
}
/**
* @tests java.lang.ClassLoader#getSystemClassLoader()
*/
public void test_getSystemClassLoader() {
// Test for method java.lang.ClassLoader
// java.lang.ClassLoader.getSystemClassLoader()
ClassLoader cl = ClassLoader.getSystemClassLoader();
java.io.InputStream is = cl.getResourceAsStream("hyts_Foo.c");
assertNotNull("Failed to find resource from system classpath", is);
try {
is.close();
} catch (java.io.IOException e) {
}
}
/**
* @tests java.lang.ClassLoader#getSystemResource(java.lang.String)
*/
public void test_getSystemResourceLjava_lang_String() {
// Test for method java.net.URL
// java.lang.ClassLoader.getSystemResource(java.lang.String)
// Need better test...
assertNotNull("Failed to find resource: hyts_Foo.c", ClassLoader
.getSystemResource("hyts_Foo.c"));
}
//Regression Test for JIRA-2047
public void test_getResourceAsStream_withSharpChar() throws Exception {
InputStream in = this.getClass().getClassLoader().getResourceAsStream(
ClassTest.FILENAME);
assertNotNull(in);
in.close();
}
}
class DynamicPolicy extends Policy {
public PermissionCollection pc;
@Override
public PermissionCollection getPermissions(ProtectionDomain pd) {
return pc;
}
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return pc;
}
@Override
public void refresh() {
}
}
class A {
}
class Ldr extends ClassLoader {
@SuppressWarnings("deprecation")
public Class<?> define() throws Exception {
Package p = getClass().getPackage();
// Class loader paths use '/' character as separator
String path = p == null ? "" : p.getName().replace('.', '/') + '/';
InputStream is = getResourceAsStream(path + "A.class");
byte[] buf = new byte[512];
int len = is.read(buf);
return defineClass(buf, 0, len);
}
}