blob: 2e3baaed42a5f8cba1b5a179963dc93c803c152d [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 tests.api.java.net;
import dalvik.annotation.BrokenTest;
import dalvik.annotation.SideEffect;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import org.apache.harmony.security.tests.support.TestCertUtils;
import tests.support.Support_Configuration;
import tests.support.Support_PortManager;
import tests.support.Support_TestWebData;
import tests.support.Support_TestWebServer;
import tests.support.resource.Support_Resources;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import java.util.jar.Manifest;
@TestTargetClass(
value = URLClassLoader.class,
untestedMethods = {
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
notes = "findClass uses defineClass which is not implemented",
method = "findClass",
args = {java.lang.String.class}
)
}
)
public class URLClassLoaderTest extends junit.framework.TestCase {
class BogusClassLoader extends ClassLoader {
public URL getResource(String res) {
try {
return new URL("http://test/BogusClassLoader");
} catch (MalformedURLException e) {
return null;
}
}
}
public class URLClassLoaderExt extends URLClassLoader {
public URLClassLoaderExt(URL[] urls) {
super(urls);
}
public Class<?> findClass(String cl) throws ClassNotFoundException {
return super.findClass(cl);
}
}
URLClassLoader ucl;
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
}
public void checkCreateClassLoader() {
throw new SecurityException();
}
};
/**
* @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[])
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "URLClassLoader",
args = {java.net.URL[].class}
)
public void test_Constructor$Ljava_net_URL() throws MalformedURLException {
URL[] u = new URL[0];
ucl = new URLClassLoader(u);
assertTrue("Failed to set parent", ucl != null
&& ucl.getParent() == URLClassLoader.getSystemClassLoader());
URL [] urls = {new URL("http://foo.com/foo"),
new URL("jar:file://foo.jar!/foo.c"),
new URL("ftp://foo1/foo2/foo.c")};
URLClassLoader ucl1 = new URLClassLoader(urls);
assertTrue(urls.length == ucl1.getURLs().length);
try {
Class.forName("test", false, ucl);
fail("Should throw ClassNotFoundException");
} catch (ClassNotFoundException e) {
// expected
}
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
new URLClassLoader(u);
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} finally {
System.setSecurityManager(oldSm);
}
try {
new URLClassLoader(new URL[] { null });
} catch(Exception e) {
fail("Unexpected exception was thrown: " + e.getMessage());
}
}
/**
* @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[],
* java.lang.ClassLoader)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "URLClassLoader",
args = {java.net.URL[].class, java.lang.ClassLoader.class}
)
public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoader() {
ClassLoader cl = new BogusClassLoader();
URL[] u = new URL[0];
ucl = new URLClassLoader(u, cl);
URL res = ucl.getResource("J");
assertNotNull(res);
assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile());
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
new URLClassLoader(u, cl);
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} finally {
System.setSecurityManager(oldSm);
}
}
/**
* @tests java.net.URLClassLoader#findResources(java.lang.String)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "IOException checking missing. "
+ "A test case that loads a resource from a webserver is missing.",
method = "findResources",
args = {java.lang.String.class}
)
@SideEffect("Support_TestWebServer requires isolation.")
public void test_findResourcesLjava_lang_String() throws Exception {
Enumeration<URL> res = null;
String[] resValues = { "This is a test resource file.",
"This is a resource from a subdir"};
String tmp = System.getProperty("java.io.tmpdir") + "/";
File tmpDir = new File(tmp);
File test1 = new File(tmp + "test0");
test1.deleteOnExit();
FileOutputStream out = new FileOutputStream(test1);
out.write(resValues[0].getBytes());
out.flush();
out.close();
File subDir = new File(tmp + "subdir/");
subDir.mkdir();
File test2 = new File(tmp + "subdir/test0");
test2.deleteOnExit();
out = new FileOutputStream(test2);
out.write(resValues[1].getBytes());
out.flush();
out.close();
URL[] urls = new URL[2];
urls[0] = new URL("file://" + tmpDir.getAbsolutePath() + "/");
urls[1] = new URL("file://" + subDir.getAbsolutePath() + "/");
ucl = new URLClassLoader(urls);
res = ucl.findResources("test0");
assertNotNull("Failed to locate resources", res);
int i = 0;
while (res.hasMoreElements()) {
StringBuffer sb = getResContent(res.nextElement());
assertEquals("Returned incorrect resource/or in wrong order",
resValues[i++], sb.toString());
}
assertEquals("Incorrect number of resources returned", 2, i);
}
/**
* @tests java.net.URLClassLoader#getURLs()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getURLs",
args = {}
)
public void test_getURLs() throws MalformedURLException {
URL[] urls = new URL[4];
urls[0] = new URL("http://" + Support_Configuration.HomeAddress);
urls[1] = new URL("http://" + Support_Configuration.TestResources + "/");
urls[2] = new URL("ftp://" + Support_Configuration.TestResources + "/");
urls[3] = new URL("jar:file:c://" + Support_Configuration.TestResources
+ "!/");
ucl = new URLClassLoader(urls);
URL[] ucUrls = ucl.getURLs();
for (int i = 0; i < urls.length; i++) {
assertEquals("Returned incorrect URL[]", urls[i], ucUrls[i]);
}
}
/**
* @tests java.net.URLClassLoader#newInstance(java.net.URL[])
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "newInstance",
args = {java.net.URL[].class}
)
@BrokenTest("web address used from support doesn't work anymore")
public void test_newInstance$Ljava_net_URL() throws MalformedURLException,
ClassNotFoundException {
// Verify that loaded class' have correct permissions
Class cl = null;
URL res = null;
URL[] urls = new URL[1];
urls[0] = new URL(Support_Resources.getResourceURL("/UCL/UCL.jar"));
ucl = URLClassLoader.newInstance(urls);
cl = ucl.loadClass("ucl.ResClass");
res = cl.getClassLoader().getResource("XX.class");
assertNotNull("Failed to load class", cl);
assertNotNull(
"Loaded class unable to access resource from same codeSource",
res);
cl = null;
urls[0] = new URL("jar:"
+ Support_Resources.getResourceURL("/UCL/UCL.jar!/"));
ucl = URLClassLoader.newInstance(urls);
cl = ucl.loadClass("ucl.ResClass");
assertNotNull("Failed to load class from explicit jar URL", cl);
}
/**
* @tests java.net.URLClassLoader#newInstance(java.net.URL[],
* java.lang.ClassLoader)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "newInstance",
args = {java.net.URL[].class, java.lang.ClassLoader.class}
)
public void test_newInstance$Ljava_net_URLLjava_lang_ClassLoader() {
ClassLoader cl = new BogusClassLoader();
URL[] u = new URL[0];
ucl = URLClassLoader.newInstance(u, cl);
URL res = ucl.getResource("J");
assertNotNull(res);
assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile());
}
/**
* @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[],
* java.lang.ClassLoader, java.net.URLStreamHandlerFactory)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "URLClassLoader",
args = {java.net.URL[].class, java.lang.ClassLoader.class,
java.net.URLStreamHandlerFactory.class}
)
public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoaderLjava_net_URLStreamHandlerFactory() {
class TestFactory implements URLStreamHandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
return null;
}
}
ClassLoader cl = new BogusClassLoader();
URL[] u = new URL[0];
ucl = new URLClassLoader(u, cl, new TestFactory());
URL res = ucl.getResource("J");
assertNotNull(res);
assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile());
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
new URLClassLoader(u, cl, new TestFactory());
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} finally {
System.setSecurityManager(oldSm);
}
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "addURL",
args = { URL.class }
)
public void test_addURLLjava_net_URL() throws MalformedURLException {
URL[] u = new URL[0];
URL [] urls = {new URL("http://foo.com/foo"),
new URL("jar:file://foo.jar!/foo.c"),
new URL("ftp://foo1/foo2/foo.c"), null};
TestURLClassLoader tucl = new TestURLClassLoader(u);
for(int i = 0; i < urls.length;) {
tucl.addURL(urls[i]);
i++;
URL [] result = tucl.getURLs();
assertEquals("Result array length is incorrect: " + i,
i, result.length);
for(int j = 0; j < result.length; j++) {
assertEquals("Result array item is incorrect: " + j,
urls[j], result[j]);
}
}
}
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = "",
method = "getPermissions",
args = { CodeSource.class }
)
public void test_getPermissions() throws MalformedURLException {
URL url = new URL("http://" + Support_Configuration.SpecialInetTestAddress);
Certificate[] chain = TestCertUtils.getCertChain();
CodeSource cs = new CodeSource(url, chain);
TestURLClassLoader cl = new TestURLClassLoader(new URL[] {url});
PermissionCollection permCol = cl.getPermissions(cs);
assertNotNull(permCol);
URL url1 = new URL("file://foo/foo.c");
TestURLClassLoader cl1 = new TestURLClassLoader(new URL[] {url});
CodeSource cs1 = new CodeSource(url1, chain);
PermissionCollection permCol1 = cl1.getPermissions(cs1);
assertNotNull(permCol1);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "definePackage",
args = { java.lang.String.class, java.util.jar.Manifest.class,
java.net.URL.class }
)
public void test_definePackage() throws MalformedURLException {
Manifest manifest = new Manifest();
URL[] u = new URL[0];
TestURLClassLoader tucl = new TestURLClassLoader(u);
URL [] urls = {new URL("http://foo.com/foo"),
new URL("jar:file://foo.jar!/foo.c"),
new URL("ftp://foo1/foo2/foo.c"),
new URL("file://new/package/name/"),
null};
String packageName = "new.package.name";
for(int i = 0; i < urls.length; i++) {
Package pack = tucl.definePackage(packageName + i, manifest, urls[i]);
assertEquals(packageName + i, pack.getName());
assertNull("Implementation Title is not null",
pack.getImplementationTitle());
assertNull("Implementation Vendor is not null",
pack.getImplementationVendor());
assertNull("Implementation Version is not null.",
pack.getImplementationVersion());
}
try {
tucl.definePackage(packageName + "0", manifest, null);
fail("IllegalArgumentException was not thrown.");
} catch(IllegalArgumentException iae) {
//expected
}
}
class TestURLClassLoader extends URLClassLoader {
public TestURLClassLoader(URL[] urls) {
super(urls);
}
public void addURL(URL url) {
super.addURL(url);
}
public Package definePackage(String name,
Manifest man,
URL url)
throws IllegalArgumentException {
return super.definePackage(name, man, url);
}
public Class<?> findClass(String name)
throws ClassNotFoundException {
return super.findClass(name);
}
protected PermissionCollection getPermissions(CodeSource codesource) {
return super.getPermissions(codesource);
}
}
/**
* @tests java.net.URLClassLoader#findResource(java.lang.String)
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "findResource",
args = {java.lang.String.class}
)
@SideEffect("Support_TestWebServer requires isolation.")
public void test_findResourceLjava_lang_String() throws Exception {
int port = Support_PortManager.getNextPort();
File tmp = File.createTempFile("test", ".txt");
Support_TestWebServer server = new Support_TestWebServer();
try {
server.initServer(port, tmp.getAbsolutePath(), "text/html");
URL[] urls = { new URL("http://localhost:" + port + "/") };
ucl = new URLClassLoader(urls);
URL res = ucl.findResource("test1");
assertNotNull("Failed to locate resource", res);
StringBuffer sb = getResContent(res);
assertEquals("Returned incorrect resource", new String(Support_TestWebData.test1),
sb.toString());
} finally {
server.close();
}
}
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Checks getResource, indirectly checks findResource",
clazz = ClassLoader.class,
method = "getResource",
args = {java.lang.String.class}
),
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Checks getResource, indirectly checks findResource",
method = "findResource",
args = {java.lang.String.class}
)
})
public void testFindResource_H3461() throws Exception {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
File dir = new File(tmpDir, "encode#me");
File f, f2;
URLClassLoader loader;
URL dirUrl;
if (!dir.exists()) {
dir.mkdir();
}
dir.deleteOnExit();
dirUrl = dir.toURI().toURL();
loader = new URLClassLoader( new URL[] { dirUrl });
f = File.createTempFile("temp", ".dat", dir);
f.deleteOnExit();
f2 = File.createTempFile("bad#name#", ".dat", dir);
f2.deleteOnExit();
assertNotNull("Unable to load resource from path with problematic name",
loader.getResource(f.getName()));
assertEquals("URL was not correctly encoded",
f2.toURI().toURL(),
loader.getResource(f2.getName()));
}
/**
* @tests java.net.URLClassLoader#getResource(java.lang.String)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getResource",
args = {java.lang.String.class}
)
public void test_getResourceLjava_lang_String()
throws MalformedURLException {
URL url1 = new URL("file:///");
URLClassLoader loader = new URLClassLoader(new URL[] { url1 });
long start = System.currentTimeMillis();
// try without the leading /
URL result = loader.getResource("dir1/file1");
long end = System.currentTimeMillis();
long time = end - start;
if (time < 100) {
time = 100;
}
start = System.currentTimeMillis();
// try with the leading forward slash
result = loader.getResource("/dir1/file1");
end = System.currentTimeMillis();
long uncTime = end - start;
assertTrue("too long. UNC path formed? UNC time: " + uncTime
+ " regular time: " + time, uncTime <= (time * 4));
}
/**
* Regression for Harmony-2237
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Regression test",
method = "findResource",
args = {java.lang.String.class}
)
@SideEffect("Support_TestWebServer requires isolation.")
public void test_findResource_String() throws Exception {
File tempFile1 = File.createTempFile("textFile", ".txt");
tempFile1.createNewFile();
tempFile1.deleteOnExit();
File tempFile2 = File.createTempFile("jarFile", ".jar");
tempFile2.delete();
tempFile2.deleteOnExit();
Support_TestWebServer server = new Support_TestWebServer();
int port = Support_PortManager.getNextPort();
try {
server.initServer(port, false);
String tempPath1 = tempFile1.getParentFile().getAbsolutePath() + "/";
InputStream is = getClass().getResourceAsStream(
"/tests/resources/hyts_patch.jar");
Support_Resources.copyLocalFileto(tempFile2, is);
String tempPath2 = tempFile2.getAbsolutePath();
String tempPath3 = "http://localhost:" + port + "/";
URLClassLoader urlLoader = getURLClassLoader(tempPath1, tempPath2);
assertNull("Found inexistant resource",
urlLoader.findResource("XXX")); //$NON-NLS-1$
assertNotNull("Couldn't find resource from directory",
urlLoader.findResource(tempFile1.getName())); //$NON-NLS-1$
assertNotNull("Couldn't find resource from jar",
urlLoader.findResource("Blah.txt")); //$NON-NLS-1$
urlLoader = getURLClassLoader(tempPath1, tempPath2, tempPath3);
assertNotNull("Couldn't find resource from web",
urlLoader.findResource("test1")); //$NON-NLS-1$
assertNull("Found inexistant resource from web",
urlLoader.findResource("test3")); //$NON-NLS-1$
} finally {
server.close();
}
}
private static URLClassLoader getURLClassLoader(String... classPath)
throws MalformedURLException {
List<URL> urlList = new ArrayList<URL>();
for (String path : classPath) {
String url;
File f = new File(path);
if (f.isDirectory()) {
url = "file:" + path;
} else if (path.startsWith("http")) {
url = path;
} else {
url = "jar:file:" + path + "!/";
}
urlList.add(new URL(url));
}
return new URLClassLoader(urlList.toArray(new URL[urlList.size()]));
}
private StringBuffer getResContent(URL res) throws IOException {
StringBuffer sb = new StringBuffer();
InputStream is = res.openStream();
int c;
while ((c = is.read()) != -1) {
sb.append((char) c);
}
is.close();
return sb;
}
}