new map creation in multiple threads throws java.util.NoSuchElementException
amirkamran opened this issue · 10 comments
Exception in thread "pool-1-thread-1" java.util.NoSuchElementException
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:340)
at java.util.ServiceLoader$1.next(ServiceLoader.java:428)
at net.openhft.koloboke.collect.map.hash.HashIntDoubleMaps.getDefaultFactory(HashIntDoubleMaps.java:56)
at net.openhft.koloboke.collect.map.hash.HashIntDoubleMaps.newMutableMap(HashIntDoubleMaps.java:81)
at Test.run(Test.java:18)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Please try to synchronize map creation externally, for example, extract a static synchronized
method which creates IntDoubleMap
s. If problem disappears, I will synchronize HashIntDoubleMaps.getDefaultFactory()
method.
Yes, that solves the issue.
I'll publish version with a fix tomorrow -- please check then.
@leventov thanks .. it works !
I have 0.6.6 and still get this error, both in the java 7 and java 8 versions. Specifically, I have a function: private static synchronized HashCharCharMapFactory getHashCharCharMapFactory() {
return HashCharCharMaps.getDefaultFactory();
}
that when called gives the following exception: Exception in thread "main" java.lang.ExceptionInInitializerError
at net.openhft.koloboke.collect.map.hash.HashCharCharMaps.getDefaultFactory(HashCharCharMaps.java:52)
at KolobokeVsFastUtilDemo.getHashCharCharMapFactory(KolobokeVsFastUtilDemo.java:65)
at KolobokeVsFastUtilDemo.main(KolobokeVsFastUtilDemo.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
@leventov I am still seeing this issue (or one similar to it) when using version 0.6.8 with Java 8:
java.lang.ExceptionInInitializerError
at net.openhft.koloboke.collect.set.hash.HashIntSets.getDefaultFactory(HashIntSets.java:49)
at net.openhft.koloboke.collect.set.hash.HashIntSets.newMutableSet(HashIntSets.java:68)
at com.test.benchmark.KolobokeCollectionsBenchmark.getSet(KolobokeCollectionsBenchmark.java:48)
at com.test.benchmark.KolobokeCollectionsBenchmark.kolobokieSetBenchmark(KolobokeCollectionsBenchmark.java:34)
at com.test.benchmark.generated.KolobokeCollectionsBenchmark_kolobokieSetBenchmark_jmhTest.kolobokieSetBenchmark_thrpt_jmhStub(KolobokeCollectionsBenchmark_kolobokieSetBenchmark_jmhTest.java:104)
at com.test.benchmark.generated.KolobokeCollectionsBenchmark_kolobokieSetBenchmark_jmhTest.kolobokieSetBenchmark_Throughput(KolobokeCollectionsBenchmark_kolobokieSetBenchmark_jmhTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:430)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:412)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.NoSuchElementException
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:365)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at net.openhft.koloboke.collect.set.hash.HashIntSets$DefaultFactoryHolder.<clinit>(HashIntSets.java:36)
... 16 more
I have followed the advice in this thread to create the set (or map -- seeing the same issue when using the factory for map creation) in a static, synchronized method, but no luck. Please let me know if I should open another issue or if you need any additional information.
@jdpgrailsdev the synchronization issue has been solved -- you shouldn't create a Set in a synchronized block.
Please check that you have both -api
and -impl
jars in the classpath, e. g. using Maven:
<dependencies>
<dependency>
<groupId>net.openhft</groupId>
<artifactId>koloboke-api-jdk8</artifactId>
<version>0.6.8</version>
</dependency>
<dependency>
<groupId>net.openhft</groupId>
<artifactId>koloboke-impl-jdk8</artifactId>
<version>0.6.8</version>
</dependency>
<dependencies>
@leventov
I can confirm that I have both on the classpath (using Gradle):
ext {
kolobokeVersion = '0.6.8'
}
dependencies {
compile "net.openhft:koloboke-api-jdk8:${kolobokeVersion}"
runtime "net.openhft:koloboke-impl-jdk8:${kolobokeVersion}"
}
I tried going back to creating the map/set in a non-synchronized fashion, but I still get the same error:
java.lang.ExceptionInInitializerError
at net.openhft.koloboke.collect.map.hash.HashIntIntMaps.getDefaultFactory(HashIntIntMaps.java:52)
at net.openhft.koloboke.collect.map.hash.HashIntIntMaps.newMutableMap(HashIntIntMaps.java:76)
at com.test.benchmark.KolobokeCollectionsBenchmark.getMap(KolobokeCollectionsBenchmark.java:41)
at com.test.benchmark.KolobokeCollectionsBenchmark.kolobokeMapBenchmark(KolobokeCollectionsBenchmark.java:26)
at com.test.benchmark.generated.KolobokeCollectionsBenchmark_kolobokeMapBenchmark_jmhTest.kolobokeMapBenchmark_thrpt_jmhStub(KolobokeCollectionsBenchmark_kolobokeMapBenchmark_jmhTest.java:104)
at com.test.benchmark.generated.KolobokeCollectionsBenchmark_kolobokeMapBenchmark_jmhTest.kolobokeMapBenchmark_Throughput(KolobokeCollectionsBenchmark_kolobokeMapBenchmark_jmhTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:430)
at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:412)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.NoSuchElementException
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:365)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at net.openhft.koloboke.collect.map.hash.HashIntIntMaps$DefaultFactoryHolder.<clinit>(HashIntIntMaps.java:37)
... 16 more
Here is an example of how I am creating the map:
private Map<Integer, Integer> map = null;
...
public void someMethod(final Integer key) {
if(getMap().containsKey(key)) {
...
}
}
private Map<Integer,Integer> getMap() {
if(map == null) {
map = HashIntIntMaps.newMutableMap();
}
return map;
}
Previously, the getMap
method was a static, synchronized method, but that too produced the same error.