// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package jodd.util;
import jodd.io.FileUtil;
import jodd.util.cl.ExtendedURLClassLoader;
import jodd.util.fixtures.testdata.A;
import org.junit.Assert;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class ExtendedURLClassLoaderTest {
private final URLClassLoader cl = (URLClassLoader) this.getClass().getClassLoader();
@Test
public void testLoadSystemClasses() throws ClassNotFoundException {
URL[] urls = new URL[0];
// parent-first
ExtendedURLClassLoader cl1 = new ExtendedURLClassLoader(urls, cl, true);
Class c1 = cl1.loadClass("java.lang.String");
assertEquals(String.class, c1);
// parent-last, still loaded by system loader
ExtendedURLClassLoader cl2 = new ExtendedURLClassLoader(urls, cl, false);
Class c2 = cl2.loadClass("java.lang.String");
assertEquals(String.class, c2);
assertEquals(c1, c2);
}
@Test
public void testParentFirst() throws ClassNotFoundException {
URLClassLoader parentCL = (URLClassLoader) A.class.getClassLoader();
URL[] urls = parentCL.getURLs();
// parent-first
ExtendedURLClassLoader ecl = new ExtendedURLClassLoader(urls, parentCL, true);
Class c1 = ecl.loadClass(A.class.getName());
assertTrue(A.class.equals(c1));
// force loader
ecl = new ExtendedURLClassLoader(urls, parentCL, true);
ecl.addLoaderOnlyRules(A.class.getPackage().getName() + ".*");
c1 = ecl.loadClass(A.class.getName());
assertFalse(A.class.equals(c1));
// force parent, no loader
URLClassLoader ucl = new URLClassLoader(new URL[0], null);
ecl = new ExtendedURLClassLoader(urls, ucl, true);
ecl.addParentOnlyRules(A.class.getName());
try {
ecl.loadClass(A.class.getName());
Assert.fail();
} catch (ClassNotFoundException ignore) {}
}
@Test
public void testParentLast() throws ClassNotFoundException {
URLClassLoader parentCL = (URLClassLoader) A.class.getClassLoader();
URL[] urls = parentCL.getURLs();
// parent-last
ExtendedURLClassLoader ecl = new ExtendedURLClassLoader(urls, parentCL, false);
Class c1 = ecl.loadClass(A.class.getName());
assertFalse(A.class.equals(c1));
// force parent
ecl = new ExtendedURLClassLoader(urls, parentCL, false);
ecl.addParentOnlyRules(A.class.getPackage().getName() + ".*");
c1 = ecl.loadClass(A.class.getName());
assertTrue(A.class.equals(c1));
// force loader, no parent
ecl = new ExtendedURLClassLoader(new URL[0], parentCL, false);
ecl.addLoaderOnlyRules(A.class.getName());
try {
ecl.loadClass(A.class.getName());
Assert.fail();
} catch (ClassNotFoundException ignore) {}
}
@Test
public void testGetResource() throws IOException {
File tempRoot = FileUtil.createTempDirectory("jodd", "tmp");
File temp = new File(tempRoot, "pckg");
FileUtil.mkdir(temp);
File resourceFile = new File(temp, "data");
FileUtil.writeString(resourceFile, "RESOURCE CONTENT");
resourceFile.deleteOnExit();
URL[] urls = new URL[] {FileUtil.toURL(tempRoot)};
// parent-first
ExtendedURLClassLoader ecl = new ExtendedURLClassLoader(urls, cl, true);
URL res = ecl.getResource("pckg/data");
assertEquals(res, FileUtil.toURL(resourceFile));
Enumeration<URL> enums = ecl.getResources("pckg/data");
assertTrue(enums.hasMoreElements());
assertEquals(res, enums.nextElement());
// parent-first, parent-only
ecl = new ExtendedURLClassLoader(urls, cl, true);
ecl.addParentOnlyRules("pckg.data");
res = ecl.getResource("pckg/data");
assertNull(res);
//// dot variant
ecl = new ExtendedURLClassLoader(urls, cl, true);
ecl.setMatchResourcesAsPackages(false);
ecl.addParentOnlyRules("pckg/data");
res = ecl.getResource("pckg/data");
assertNull(res);
// parent-last
ecl = new ExtendedURLClassLoader(urls, cl, false);
res = ecl.getResource("pckg/data");
assertEquals(res, FileUtil.toURL(resourceFile));
enums = ecl.getResources("pckg/data");
assertTrue(enums.hasMoreElements());
assertEquals(res, enums.nextElement());
// parent-last, parent-only
ecl = new ExtendedURLClassLoader(urls, cl, false);
ecl.addLoaderOnlyRules("pckg.data");
res = ecl.getResource("pckg/data");
assertEquals(res, FileUtil.toURL(resourceFile));
ecl.addParentOnlyRules("pckg.data");
res = ecl.getResource("pckg/data");
assertNull(res);
//// dot variant
ecl = new ExtendedURLClassLoader(urls, cl, false);
ecl.setMatchResourcesAsPackages(false);
ecl.addLoaderOnlyRules("pckg/data");
res = ecl.getResource("pckg/data");
assertEquals(res, FileUtil.toURL(resourceFile));
ecl.addParentOnlyRules("pckg.data");
res = ecl.getResource("pckg/data");
assertNotNull(res);
ecl.addParentOnlyRules("pckg/data");
res = ecl.getResource("pckg/data");
assertNull(res);
FileUtil.deleteDir(tempRoot);
}
}