I am creating a program using Optaplanner, and I keep getting this exception but only on rare occassions, most of the time I can execute my program without problems, and it's hard to recreate the issue, since it only happens sometimes...
Exception in thread "main" java.util.ConcurrentModificationException: java.util.ConcurrentModificationException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
at org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryConfig.java:503)
at org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildScoreDirectorFactory(ScoreDirectorFactoryConfig.java:331)
at org.optaplanner.core.config.solver.SolverConfig.buildSolver(SolverConfig.java:220)
at org.optaplanner.core.impl.solver.AbstractSolverFactory.buildSolver(AbstractSolverFactory.java:61)
at org.avalin.optaplanner.main.EmployeeRoster.buildEvaluationSolver(EmployeeRoster.java:247)
at org.avalin.optaplanner.main.EmployeeRoster.main(EmployeeRoster.java:82)
Caused by: java.util.ConcurrentModificationException
at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1138)
...
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:747)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:283)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1603)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
Here's the buildEvaluationSolver method that it seems to happen at:
private static Solver buildEvaluationSolver()
{
SolverFactory solverFactory = SolverFactory.createFromXmlResource(EVALUATION_CONFIG_XML);
return solverFactory.buildSolver();
}
I assume something is getting iterated while changed at the same time, but the hardest part for me is to figure out how/where exactly, if it's my code, something with xstream while creatingfromxmlresource or something third.
Hope this makes sense to some
EDIT: I learned I should probably have included the warnings
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/Users/path/my.jar) to field java.util.TreeMap.comparator
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Problem seemed to stem from the computer that got this error was using JDK9, and it usually works fine with JDK8. We downgraded to JDK8 on the given computer, and have since not seen the error.
You're probably modifying the same solverFactory
instance from different threads by calling solverFactory.getSolverConfig()
(for example to configure the termination time limit dynamically).
Solution: Look in the docs for SolverFactory.cloneSolverFactory()
.