Uploaded image for project: 'Spatial Information Systems'
  1. Spatial Information Systems
  2. SIS-193

Remove the workaround for ServiceLoader bug

    XMLWordPrintableJSON

Details

    • Task
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 0.6, 0.7, 0.8, 1.0, 1.1, 1.2, 1.3
    • 1.4
    • Referencing

    Description

      As of 1.8.0_31-b13, java.util.ServiceLoader does not support usage of a second Iterator in the middle of a previous iteration. The following Java code provides two simple tests with a ServiceLoader iterating over two elements.

      import java.util.Iterator;
      import java.util.ServiceLoader;
      
      public class ServiceLoaderTest {
          public static class I1 extends ServiceLoaderTest {}  // A dummy provider.
          public static class I2 extends ServiceLoaderTest {}  // An other provider.
      
          public static void main(String[] args) {
              test1();
              test2();
          }
      
          private static void test1() {
              System.out.println();
              System.out.println("---- TEST 1 ----");
              ServiceLoader<ServiceLoaderTest> loader = ServiceLoader.load(ServiceLoaderTest.class);
      
              Iterator<ServiceLoaderTest> it1 = loader.iterator();
              System.out.println("it1.hasNext() = " + it1.hasNext());
              System.out.println("it1.next()    = " + it1.next());
      
              Iterator<ServiceLoaderTest> it2 = loader.iterator();
              System.out.println("it2.hasNext() = " + it2.hasNext());
              System.out.println("it2.next()    = " + it2.next());
      
              System.out.println("it1.hasNext() = " + it1.hasNext());
              System.out.println("it1.next()    = " + it1.next());
      
              System.out.println("it2.hasNext() = " + it2.hasNext());  // Expected "true" here, but get "false".
          }
      
          private static void test2() {
              System.out.println();
              System.out.println("---- TEST 2 ----");
              ServiceLoader<ServiceLoaderTest> loader = ServiceLoader.load(ServiceLoaderTest.class);
      
              Iterator<ServiceLoaderTest> it1 = loader.iterator();
              System.out.println("it1.hasNext() = " + it1.hasNext());
              System.out.println("it1.next()    = " + it1.next());
      
              Iterator<ServiceLoaderTest> it2 = loader.iterator();
              System.out.println("it1.hasNext() = " + it1.hasNext());
              System.out.println("it2.hasNext() = " + it2.hasNext());
              System.out.println("it1.next()    = " + it1.next());
              System.out.println("it2.next()    = " + it2.next());  // ConcurrentModificationException here.
          }
      }
      

      The second test throws the following exception:

          Exception in thread "main" java.util.ConcurrentModificationException
          	at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:711)
          	at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:744)
          	at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:742)
          	at java.util.ServiceLoader$1.next(ServiceLoader.java:479)
          	at test.ServiceLoaderTest.test2(ServiceLoaderTest.java:47)
          	at test.ServiceLoaderTest.main(ServiceLoaderTest.java:12)
      

      The workaround applied in Apache SIS has been to add a LazySet internal class which wraps an Iterable and caches its values. But this is a little bit unfortunate since ServiceLoader already caches its values.

      ServiceLoader is probably going to be significantly rewritten in JDK9 as a side effect of the Jigsaw project. So we should revisit if our LazySet workaround is still needed on a JDK9 branch.

      Attachments

        Issue Links

          Activity

            People

              desruisseaux Martin Desruisseaux
              desruisseaux Martin Desruisseaux
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: