ConcurrentModificationException in java.util.ServiceLoader (not a multi-thread issue)
Martin Desruisseaux
martin.desruisseaux at geomatys.fr
Mon Feb 23 18:05:55 UTC 2015
Apparently the test case that I attached to my previous email was list.
There is a copy-and-paste of the 2 tests reproducing the ServiceLoader
issue:
package test;
import java.util.Iterator;
import java.util.ServiceLoader;
public class ServiceLoaderTest {
public static class I1 extends ServiceLoaderTest {}
public static class I2 extends ServiceLoaderTest {}
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.
}
}
Martin
Le 23/02/15 15:20, Martin Desruisseaux a écrit :
> Hello all
>
> java.util.ServiceLoader does not seem to support usage of a second
> Iterator in the middle of a previous iteration. The attached Java file
> provides two simple tests with a ServiceLoader iterating over two
> elements. The first test creates two iterators and invokes their
> hasNext() / next() methods in the following order:
>
> * Iterator 1
> * Iterator 2
> * Iterator 1
> * Iterator 2 - unexpected end of iteration here.
>
> The second test creates two iterators and invoke the hasNext() methods
> on both iterators before to invoke their next() methods. This result is
> the following exception (tested on 1.8.0_31-b13):
>
> 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)
>
> (note: to run the test, the attached test.ServiceLoaderTest file needs
> to be in the META-INF/services/ directory). I found a Stackoverflow
> thread mentioning this issue 4 years ago [1], but apparently without
> solution. Should I look for a patch, or is the current behaviour
> considered okay (in which case I would suggest to warn the users in the
> Javadoc)?
>
>
> Martin
>
>
> [1] http://stackoverflow.com/questions/2593777/serviceloader-double-iterator-issues
>
>
More information about the core-libs-dev
mailing list