@SuppressWarnings( { "nls", "unchecked" })
public void test_loadLjava_lang_ClassLjava_lang_ClassLoader()
throws MalformedURLException {
URLClassLoader ucl = new URLClassLoader(new URL[] { jarFile });
// normal config file
ServiceLoader serviceLoader = ServiceLoader.load(Service.class, ucl);
Iterator itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfService", ((Service) itr.next())
.myNameIs());
assertFalse(itr.hasNext());
// class that can not cast correctly
serviceLoader = ServiceLoader.load(ServiceFinalClass.class, ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
try {
itr.next();
fail("Should throw ServiceConfigurationError");
} catch (ServiceConfigurationError e) {
// expected
}
// abstract class with comment in config file
serviceLoader = ServiceLoader.load(AbstractService.class, ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfAbstractService", ((AbstractService) itr
.next()).myNameIs());
assertFalse(itr.hasNext());
// one service with two implementation class
serviceLoader = ServiceLoader.load(ServiceMoreThanOne.class, ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
String name = ((ServiceMoreThanOne) itr.next()).myNameIs();
if ("ImplementationOfServiceMoreThanOne1".equals(name)) {
assertEquals("ImplementationOfServiceMoreThanOne2",
((ServiceMoreThanOne) itr.next()).myNameIs());
} else if ("ImplementationOfServiceMoreThanOne2".equals(name)) {
assertEquals("ImplementationOfServiceMoreThanOne1",
((ServiceMoreThanOne) itr.next()).myNameIs());
} else {
fail("Should load ImplementationOfServiceMoreThanOne1 or ImplementationOfServiceMoreThanOne2");
}
assertFalse(itr.hasNext());
// config file only contains comments
serviceLoader = ServiceLoader.load(ServiceForAllCommentTest.class, ucl);
itr = serviceLoader.iterator();
assertFalse(itr.hasNext());
try {
itr.next();
fail("Should throw NoSuchElementException");
} catch (NoSuchElementException e) {
// expected
}
// empty config file
serviceLoader = ServiceLoader.load(ServiceForEmptyTest.class, ucl);
itr = serviceLoader.iterator();
assertFalse(itr.hasNext());
try {
itr.next();
fail("Should throw NoSuchElementException");
} catch (NoSuchElementException e) {
// expected
}
// config file with illegal char
serviceLoader = ServiceLoader
.load(ServiceForIllegalNameTest.class, ucl);
itr = serviceLoader.iterator();
try {
itr.hasNext();
fail("Should throw ServiceConfigurationError");
} catch (ServiceConfigurationError e) {
// expected
}
// config file with legal string, but the class does not exist
serviceLoader = ServiceLoader.load(ServiceForWrongNameTest.class, ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
try {
itr.next();
fail("Should throw ServiceConfigurationError");
} catch (ServiceConfigurationError e) {
// expected
}
// config file for an internal class
serviceLoader = ServiceLoader.load(
AbstractService.InternalService.class, ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfAbstractServiceInternalService",
((AbstractService.InternalService) itr.next())
.myInternalNameIs());
assertFalse(itr.hasNext());
// config files in the 2 jar files
serviceLoader = ServiceLoader.load(ServiceIn2File.class, ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfServiceIn2File1", ((ServiceIn2File) itr
.next()).myNameIs());
assertFalse(itr.hasNext());
// add the second file
URL jarFile2 = prepairJar("hyts_services2.jar");
URLClassLoader ucl2 = new URLClassLoader(
new URL[] { jarFile, jarFile2 });
serviceLoader = ServiceLoader.load(ServiceIn2File.class, ucl2);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
name = ((ServiceIn2File) itr.next()).myNameIs();
if ("ImplementationOfServiceIn2File1".equals(name)) {
assertEquals("ImplementationOfServiceIn2File2",
((ServiceIn2File) itr.next()).myNameIs());
} else if ("ImplementationOfServiceIn2File2".equals(name)) {
assertEquals("ImplementationOfServiceIn2File1",
((ServiceIn2File) itr.next()).myNameIs());
} else {
fail("Should load ImplementationOfServiceIn2File1 or ImplementationOfServiceIn2File2");
}
assertFalse(itr.hasNext());
// same config files in 2 jar files
serviceLoader = ServiceLoader.load(ServiceDuplicateIn2File.class, ucl2);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfServiceDuplicateIn2File_1",
((ServiceDuplicateIn2File) itr.next()).myNameIs());
assertFalse(itr.hasNext());
ucl2 = new URLClassLoader(new URL[] { jarFile2, jarFile });
serviceLoader = ServiceLoader.load(ServiceDuplicateIn2File.class, ucl2);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfServiceDuplicateIn2File_2",
((ServiceDuplicateIn2File) itr.next()).myNameIs());
assertFalse(itr.hasNext());
// one config file in one jar, another empty config in another jar.
serviceLoader = ServiceLoader.load(ServiceIn2FileWithEmptyConfig.class,
ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfServiceIn2FileWithEmptyConfig",
((ServiceIn2FileWithEmptyConfig) itr.next()).myNameIs());
assertFalse(itr.hasNext());
ucl2 = new URLClassLoader(new URL[] { jarFile, jarFile2 });
serviceLoader = ServiceLoader.load(ServiceIn2FileWithEmptyConfig.class,
ucl2);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfServiceIn2FileWithEmptyConfig",
((ServiceIn2FileWithEmptyConfig) itr.next()).myNameIs());
assertFalse(itr.hasNext());
// config file with duplicate items
serviceLoader = ServiceLoader.load(ServiceWithDuplicateSons.class, ucl);
itr = serviceLoader.iterator();
assertTrue(itr.hasNext());
assertEquals("ImplementationOfServiceWithDuplicateSons",
((ServiceWithDuplicateSons) itr.next()).myNameIs());
assertFalse(itr.hasNext());
// can not load by system classloader
serviceLoader = ServiceLoader.load(Service.class, ClassLoader
.getSystemClassLoader());
assertFalse(serviceLoader.iterator().hasNext());
// can not load by Thread.currentThread().getContextClassLoader()
serviceLoader = ServiceLoader.load(Service.class, Thread
.currentThread().getContextClassLoader());
assertFalse(serviceLoader.iterator().hasNext());
serviceLoader = ServiceLoader.load(Service.class, Service.class
.getClassLoader());
assertFalse(serviceLoader.iterator().hasNext());
// String is a final class, no sub-class for it
serviceLoader = ServiceLoader.load(String.class, ucl);
assertFalse(serviceLoader.iterator().hasNext());
}