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.util; 19 20import java.io.File; 21import java.net.MalformedURLException; 22import java.net.URL; 23import java.net.URLClassLoader; 24import java.util.Iterator; 25import java.util.NoSuchElementException; 26import java.util.ServiceConfigurationError; 27import java.util.ServiceLoader; 28 29import junit.framework.TestCase; 30import tests.resources.ServiceLoader.AbstractService; 31import tests.resources.ServiceLoader.Service; 32import tests.resources.ServiceLoader.ServiceDuplicateIn2File; 33import tests.resources.ServiceLoader.ServiceFinalClass; 34import tests.resources.ServiceLoader.ServiceForAllCommentTest; 35import tests.resources.ServiceLoader.ServiceForEmptyTest; 36import tests.resources.ServiceLoader.ServiceForIllegalNameTest; 37import tests.resources.ServiceLoader.ServiceForWrongNameTest; 38import tests.resources.ServiceLoader.ServiceIn2File; 39import tests.resources.ServiceLoader.ServiceIn2FileWithEmptyConfig; 40import tests.resources.ServiceLoader.ServiceMoreThanOne; 41import tests.resources.ServiceLoader.ServiceWithDuplicateSons; 42import tests.support.resource.Support_Resources; 43 44/** 45 * Test cases for java.util.ServiceLoader 46 */ 47public class ServiceLoaderTest extends TestCase { 48 49 private static URL jarFile = null; 50 51 /** 52 * @throws MalformedURLException 53 * @tests {@link java.util.ServiceLoader#reload()}. 54 */ 55 @SuppressWarnings("nls") 56 public void test_reload() throws MalformedURLException { 57 class SubURLClassLoader extends URLClassLoader { 58 /** 59 * @param urls 60 */ 61 public SubURLClassLoader(URL[] urls) { 62 super(urls); 63 } 64 65 @Override 66 public void addURL(URL url) { 67 super.addURL(url); 68 } 69 } 70 SubURLClassLoader ucl = new SubURLClassLoader(new URL[] { new URL( 71 "file:/no/such/file") }); 72 ServiceLoader<Service> serviceLoader = ServiceLoader.load( 73 Service.class, ucl); 74 Iterator<Service> itr = serviceLoader.iterator(); 75 assertFalse(itr.hasNext()); 76 // change the ucl to install a jar file 77 ucl.addURL(jarFile); 78 // before reload, the Iterator is unchanged 79 itr = serviceLoader.iterator(); 80 assertNotSame(itr, serviceLoader.iterator()); 81 assertFalse(itr.hasNext()); 82 // after reload, the Iterator update 83 serviceLoader.reload(); 84 itr = serviceLoader.iterator(); 85 assertTrue(itr.hasNext()); 86 assertEquals("ImplementationOfService", itr.next().myNameIs()); 87 assertFalse(itr.hasNext()); 88 } 89 90 /** 91 * @tests {@link java.util.ServiceLoader#iterator()}. 92 */ 93 @SuppressWarnings( { "nls", "unchecked" }) 94 public void test_iterator() { 95 URLClassLoader ucl = new URLClassLoader(new URL[] { jarFile }); 96 Iterator itr = ServiceLoader.load(Service.class, ucl).iterator(); 97 assertTrue(itr.hasNext()); 98 assertEquals("ImplementationOfService", ((Service) itr.next()) 99 .myNameIs()); 100 assertFalse(itr.hasNext()); 101 try { 102 itr.remove(); 103 fail("Should throw UnsupportedOperationException"); 104 } catch (UnsupportedOperationException e) { 105 // expected 106 } 107 108 itr = ServiceLoader.load(ServiceForWrongNameTest.class, ucl).iterator(); 109 assertTrue(itr.hasNext()); 110 try { 111 itr.next(); 112 fail("Should throw ServiceConfigurationError"); 113 } catch (ServiceConfigurationError e) { 114 // expected 115 } 116 try { 117 itr.remove(); 118 fail("Should throw UnsupportedOperationException"); 119 } catch (UnsupportedOperationException e) { 120 // expected 121 } 122 123 // null test 124 itr = ServiceLoader.load(null).iterator(); 125 nullIteratorTester(itr); 126 127 itr = ServiceLoader.load(null, null).iterator(); 128 nullIteratorTester(itr); 129 130 itr = ServiceLoader.load(null, ClassLoader.getSystemClassLoader()) 131 .iterator(); 132 nullIteratorTester(itr); 133 134 itr = ServiceLoader.load(Service.class, null).iterator(); 135 assertFalse(itr.hasNext()); 136 try { 137 itr.next(); 138 fail("Should throw NoSuchElementException"); 139 } catch (NoSuchElementException e) { 140 // expected 141 } 142 try { 143 itr.remove(); 144 fail("Should throw UnsupportedOperationException"); 145 } catch (UnsupportedOperationException e) { 146 // expected 147 } 148 } 149 150 @SuppressWarnings( { "nls", "unchecked" }) 151 private void nullIteratorTester(Iterator itr) { 152 assertNotNull(itr); 153 try { 154 itr.hasNext(); 155 fail("Should throw NullPointerException"); 156 } catch (NullPointerException e) { 157 // expected 158 } 159 160 try { 161 itr.next(); 162 fail("Should throw NullPointerException"); 163 } catch (NullPointerException e) { 164 // expected 165 } 166 167 try { 168 itr.remove(); 169 fail("Should throw UnsupportedOperationException"); 170 } catch (UnsupportedOperationException e) { 171 // expected 172 } 173 } 174 175 /** 176 * @throws MalformedURLException 177 * @tests {@link java.util.ServiceLoader#load(java.lang.Class, java.lang.ClassLoader)}. 178 */ 179 @SuppressWarnings( { "nls", "unchecked" }) 180 public void test_loadLjava_lang_ClassLjava_lang_ClassLoader() 181 throws MalformedURLException { 182 URLClassLoader ucl = new URLClassLoader(new URL[] { jarFile }); 183 // normal config file 184 ServiceLoader serviceLoader = ServiceLoader.load(Service.class, ucl); 185 Iterator itr = serviceLoader.iterator(); 186 assertTrue(itr.hasNext()); 187 assertEquals("ImplementationOfService", ((Service) itr.next()) 188 .myNameIs()); 189 assertFalse(itr.hasNext()); 190 191 // class that can not cast correctly 192 serviceLoader = ServiceLoader.load(ServiceFinalClass.class, ucl); 193 itr = serviceLoader.iterator(); 194 assertTrue(itr.hasNext()); 195 try { 196 itr.next(); 197 fail("Should throw ServiceConfigurationError"); 198 } catch (ServiceConfigurationError e) { 199 // expected 200 } 201 202 // abstract class with comment in config file 203 serviceLoader = ServiceLoader.load(AbstractService.class, ucl); 204 itr = serviceLoader.iterator(); 205 assertTrue(itr.hasNext()); 206 assertEquals("ImplementationOfAbstractService", ((AbstractService) itr 207 .next()).myNameIs()); 208 assertFalse(itr.hasNext()); 209 210 // one service with two implementation class 211 serviceLoader = ServiceLoader.load(ServiceMoreThanOne.class, ucl); 212 itr = serviceLoader.iterator(); 213 assertTrue(itr.hasNext()); 214 String name = ((ServiceMoreThanOne) itr.next()).myNameIs(); 215 if ("ImplementationOfServiceMoreThanOne1".equals(name)) { 216 assertEquals("ImplementationOfServiceMoreThanOne2", 217 ((ServiceMoreThanOne) itr.next()).myNameIs()); 218 } else if ("ImplementationOfServiceMoreThanOne2".equals(name)) { 219 assertEquals("ImplementationOfServiceMoreThanOne1", 220 ((ServiceMoreThanOne) itr.next()).myNameIs()); 221 } else { 222 fail("Should load ImplementationOfServiceMoreThanOne1 or ImplementationOfServiceMoreThanOne2"); 223 } 224 assertFalse(itr.hasNext()); 225 226 // config file only contains comments 227 serviceLoader = ServiceLoader.load(ServiceForAllCommentTest.class, ucl); 228 itr = serviceLoader.iterator(); 229 assertFalse(itr.hasNext()); 230 try { 231 itr.next(); 232 fail("Should throw NoSuchElementException"); 233 } catch (NoSuchElementException e) { 234 // expected 235 } 236 237 // empty config file 238 serviceLoader = ServiceLoader.load(ServiceForEmptyTest.class, ucl); 239 itr = serviceLoader.iterator(); 240 assertFalse(itr.hasNext()); 241 try { 242 itr.next(); 243 fail("Should throw NoSuchElementException"); 244 } catch (NoSuchElementException e) { 245 // expected 246 } 247 248 // config file with illegal char 249 serviceLoader = ServiceLoader 250 .load(ServiceForIllegalNameTest.class, ucl); 251 itr = serviceLoader.iterator(); 252 try { 253 itr.hasNext(); 254 fail("Should throw ServiceConfigurationError"); 255 } catch (ServiceConfigurationError e) { 256 // expected 257 } 258 259 // config file with legal string, but the class does not exist 260 serviceLoader = ServiceLoader.load(ServiceForWrongNameTest.class, ucl); 261 itr = serviceLoader.iterator(); 262 assertTrue(itr.hasNext()); 263 try { 264 itr.next(); 265 fail("Should throw ServiceConfigurationError"); 266 } catch (ServiceConfigurationError e) { 267 // expected 268 } 269 270 // config file for an internal class 271 serviceLoader = ServiceLoader.load( 272 AbstractService.InternalService.class, ucl); 273 itr = serviceLoader.iterator(); 274 assertTrue(itr.hasNext()); 275 assertEquals("ImplementationOfAbstractServiceInternalService", 276 ((AbstractService.InternalService) itr.next()) 277 .myInternalNameIs()); 278 assertFalse(itr.hasNext()); 279 280 // config files in the 2 jar files 281 serviceLoader = ServiceLoader.load(ServiceIn2File.class, ucl); 282 itr = serviceLoader.iterator(); 283 assertTrue(itr.hasNext()); 284 assertEquals("ImplementationOfServiceIn2File1", ((ServiceIn2File) itr 285 .next()).myNameIs()); 286 assertFalse(itr.hasNext()); 287 // add the second file 288 URL jarFile2 = prepairJar("hyts_services2.jar"); 289 URLClassLoader ucl2 = new URLClassLoader( 290 new URL[] { jarFile, jarFile2 }); 291 serviceLoader = ServiceLoader.load(ServiceIn2File.class, ucl2); 292 itr = serviceLoader.iterator(); 293 assertTrue(itr.hasNext()); 294 name = ((ServiceIn2File) itr.next()).myNameIs(); 295 if ("ImplementationOfServiceIn2File1".equals(name)) { 296 assertEquals("ImplementationOfServiceIn2File2", 297 ((ServiceIn2File) itr.next()).myNameIs()); 298 } else if ("ImplementationOfServiceIn2File2".equals(name)) { 299 assertEquals("ImplementationOfServiceIn2File1", 300 ((ServiceIn2File) itr.next()).myNameIs()); 301 } else { 302 fail("Should load ImplementationOfServiceIn2File1 or ImplementationOfServiceIn2File2"); 303 } 304 assertFalse(itr.hasNext()); 305 306 // same config files in 2 jar files 307 serviceLoader = ServiceLoader.load(ServiceDuplicateIn2File.class, ucl2); 308 itr = serviceLoader.iterator(); 309 assertTrue(itr.hasNext()); 310 assertEquals("ImplementationOfServiceDuplicateIn2File_1", 311 ((ServiceDuplicateIn2File) itr.next()).myNameIs()); 312 assertFalse(itr.hasNext()); 313 ucl2 = new URLClassLoader(new URL[] { jarFile2, jarFile }); 314 serviceLoader = ServiceLoader.load(ServiceDuplicateIn2File.class, ucl2); 315 itr = serviceLoader.iterator(); 316 assertTrue(itr.hasNext()); 317 assertEquals("ImplementationOfServiceDuplicateIn2File_2", 318 ((ServiceDuplicateIn2File) itr.next()).myNameIs()); 319 assertFalse(itr.hasNext()); 320 321 // one config file in one jar, another empty config in another jar. 322 serviceLoader = ServiceLoader.load(ServiceIn2FileWithEmptyConfig.class, 323 ucl); 324 itr = serviceLoader.iterator(); 325 assertTrue(itr.hasNext()); 326 assertEquals("ImplementationOfServiceIn2FileWithEmptyConfig", 327 ((ServiceIn2FileWithEmptyConfig) itr.next()).myNameIs()); 328 assertFalse(itr.hasNext()); 329 ucl2 = new URLClassLoader(new URL[] { jarFile, jarFile2 }); 330 serviceLoader = ServiceLoader.load(ServiceIn2FileWithEmptyConfig.class, 331 ucl2); 332 itr = serviceLoader.iterator(); 333 assertTrue(itr.hasNext()); 334 assertEquals("ImplementationOfServiceIn2FileWithEmptyConfig", 335 ((ServiceIn2FileWithEmptyConfig) itr.next()).myNameIs()); 336 assertFalse(itr.hasNext()); 337 338 // config file with duplicate items 339 serviceLoader = ServiceLoader.load(ServiceWithDuplicateSons.class, ucl); 340 itr = serviceLoader.iterator(); 341 assertTrue(itr.hasNext()); 342 assertEquals("ImplementationOfServiceWithDuplicateSons", 343 ((ServiceWithDuplicateSons) itr.next()).myNameIs()); 344 assertFalse(itr.hasNext()); 345 346 // can not load by system classloader 347 serviceLoader = ServiceLoader.load(Service.class, ClassLoader 348 .getSystemClassLoader()); 349 assertFalse(serviceLoader.iterator().hasNext()); 350 351 // can not load by Thread.currentThread().getContextClassLoader() 352 serviceLoader = ServiceLoader.load(Service.class, Thread 353 .currentThread().getContextClassLoader()); 354 assertFalse(serviceLoader.iterator().hasNext()); 355 356 serviceLoader = ServiceLoader.load(Service.class, Service.class 357 .getClassLoader()); 358 assertFalse(serviceLoader.iterator().hasNext()); 359 360 // String is a final class, no sub-class for it 361 serviceLoader = ServiceLoader.load(String.class, ucl); 362 assertFalse(serviceLoader.iterator().hasNext()); 363 } 364 365 /** 366 * @tests {@link java.util.ServiceLoader#load(java.lang.Class)}. 367 */ 368 @SuppressWarnings( { "nls", "unchecked" }) 369 public void test_loadLjava_lang_Class() { 370 ServiceLoader serviceLoader = ServiceLoader.load(Service.class); 371 assertFalse(serviceLoader.iterator().hasNext()); 372 // String is a final class, no sub-class for it 373 serviceLoader = ServiceLoader.load(String.class); 374 assertFalse(serviceLoader.iterator().hasNext()); 375 } 376 377 /** 378 * @param fileName 379 * @return the URL of the jar file 380 * @throws MalformedURLException 381 */ 382 @SuppressWarnings("nls") 383 private static URL prepairJar(String fileName) throws MalformedURLException { 384 File resources = Support_Resources.createTempFolder(); 385 String resPath = resources.toString(); 386 if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') { 387 resPath = resPath.substring(1); 388 } 389 Support_Resources.copyFile(resources, "ServiceLoader", fileName); 390 URL resourceURL = new URL("file:/" + resPath + "/ServiceLoader/" 391 + fileName); 392 return resourceURL; 393 } 394 395 /** 396 * @tests {@link java.util.ServiceLoader#loadInstalled(java.lang.Class)}. 397 */ 398 public void test_loadInstalledLjava_lang_Class() { 399 ServiceLoader<Service> serviceLoader = ServiceLoader 400 .loadInstalled(Service.class); 401 assertFalse(serviceLoader.iterator().hasNext()); 402 403 serviceLoader = ServiceLoader.loadInstalled(null); 404 Iterator<Service> itr = serviceLoader.iterator(); 405 nullIteratorTester(itr); 406 } 407 408 /** 409 * @tests {@link java.util.ServiceLoader#toString()}. 410 */ 411 @SuppressWarnings( { "unchecked", "nls" }) 412 public void test_toString() { 413 URLClassLoader ucl = new URLClassLoader(new URL[] { jarFile }); 414 ServiceLoader serviceLoader = ServiceLoader.load(Service.class, ucl); 415 assertTrue(serviceLoader.toString().length() > 0); 416 417 serviceLoader = ServiceLoader.load(String.class, ucl); 418 assertTrue(serviceLoader.toString().length() > 0); 419 420 serviceLoader = ServiceLoader.load(Service.class); 421 assertTrue(serviceLoader.toString().length() > 0); 422 423 serviceLoader = ServiceLoader.load(String.class); 424 assertTrue(serviceLoader.toString().length() > 0); 425 426 serviceLoader = ServiceLoader.loadInstalled(Service.class); 427 assertTrue(serviceLoader.toString().length() > 0); 428 429 serviceLoader = ServiceLoader.loadInstalled(String.class); 430 assertTrue(serviceLoader.toString().length() > 0); 431 432 serviceLoader = ServiceLoader.load(null, ucl); 433 assertNotNull(serviceLoader); 434 try { 435 serviceLoader.toString(); 436 fail("Should throw NullPointerException"); 437 } catch (NullPointerException e) { 438 // expected 439 } 440 441 serviceLoader = ServiceLoader.load(null, null); 442 assertNotNull(serviceLoader); 443 try { 444 serviceLoader.toString(); 445 fail("Should throw NullPointerException"); 446 } catch (NullPointerException e) { 447 // expected 448 } 449 450 serviceLoader = ServiceLoader.load(Service.class, null); 451 assertTrue(serviceLoader.toString().length() > 0); 452 453 serviceLoader = ServiceLoader.load(null); 454 assertNotNull(serviceLoader); 455 try { 456 serviceLoader.toString(); 457 fail("Should throw NullPointerException"); 458 } catch (NullPointerException e) { 459 // expected 460 } 461 462 serviceLoader = ServiceLoader.loadInstalled(null); 463 assertNotNull(serviceLoader); 464 try { 465 serviceLoader.toString(); 466 fail("Should throw NullPointerException"); 467 } catch (NullPointerException e) { 468 // expected 469 } 470 } 471 472 /** 473 * @see junit.framework.TestCase#setUp() 474 */ 475 @SuppressWarnings("nls") 476 @Override 477 protected void setUp() throws Exception { 478 super.setUp(); 479 jarFile = prepairJar("hyts_services.jar"); 480 } 481 482 /** 483 * @see junit.framework.TestCase#tearDown() 484 */ 485 @Override 486 protected void tearDown() throws Exception { 487 super.tearDown(); 488 new File(jarFile.getFile()).delete(); 489 } 490 491} 492