sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Martin Desruisseaux (JIRA)" <j...@apache.org>
Subject [jira] [Created] (SIS-193) Remove the workaround for ServiceLoader bug
Date Fri, 27 Feb 2015 12:09:05 GMT
Martin Desruisseaux created SIS-193:
---------------------------------------

             Summary: Remove the workaround for ServiceLoader bug
                 Key: SIS-193
                 URL: https://issues.apache.org/jira/browse/SIS-193
             Project: Spatial Information Systems
          Issue Type: Task
          Components: Referencing
            Reporter: Martin Desruisseaux
            Priority: Minor


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.

{code:java}
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.
    }
}
{code}

The second test throws the following exception:

{noformat}
    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)
{noformat}

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.




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message