2

When Maven builds my project and runs the unit tests, sometimes a concurrent modification exception is thrown (approximately 1 out of 5 times it will fail, the other times it will build successfully). But when I run the tests locally as unit tests, they all pass without the exception.

In my pom.xml file I have the Surefire plugin configured as:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <forkCount>1C</forkCount>
        <reuseForks>true</reuseForks>
    </configuration>
    <dependencies>
        <dependency>
              <groupId>org.apache.maven.surefire</groupId>
              <artifactId>surefire-junit47</artifactId>
              <version>2.19.1</version>
        </dependency>
    </dependencies>
</plugin>

However the stacktrace I get back does not mention what is causing the concurrent modification exception.

I have noticed that all tests pass on the build, but for some reason Maven reprints out the result of the test that has already passed but now has test exception ConcurrentModification.

I'm not sure what is causing the test result to be reprinted, or whether for some reason the test is being rerun at the same time while the first run of the test has not been completed since it is a parallel build? (Not sure why it would rerun a test)

Stacktrace

[Test executing]

13:48:24.869 [00001-main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@375046d6 testClass = Tests, testInstance = com.application.Tests@179181c, testMethod = failingTest@Tests, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@3f7b4a61 testClass = Tests, locations = '{}', classes = '{class com.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/app', contextLoader = 'org.springframework.test.context.web.WebDelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
13:48:24.869 [00001-main] DEBUG o.s.t.c.w.ServletTestExecutionListener - Resetting RequestContextHolder for test context [DefaultTestContext@375046d6 testClass = Tests, testInstance = com.application.Tests@179181c, testMethod = failingTest@Tests, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@3f7b4a61 testClass = Test, locations = '{}', classes = '{class com.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/app', contextLoader = 'org.springframework.test.context.web.WebDelegatingSmartContextLoader', parent = [null]]].

[Some other tests executing]

13:48:28.632 [00001-main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@54fde1bc testClass = Tests, testInstance = com.application.Tests@57ffa818, testMethod = failingTest@Tests, testException = java.util.ConcurrentModificationException, mergedContextConfiguration = [WebMergedContextConfiguration@5247834f testClass = Tests, locations = '{}', classes = '{class com.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/app', contextLoader = 'org.springframework.test.context.web.WebDelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
13:48:28.632 [00001-main] DEBUG o.s.t.c.w.ServletTestExecutionListener - Resetting RequestContextHolder for test context [DefaultTestContext@54fde1bc testClass = Tests, testInstance = com.application.Tests@57ffa818, testMethod = failingTest@Tests, testException = java.util.ConcurrentModificationException, mergedContextConfiguration = [WebMergedContextConfiguration@5247834f testClass = Tests, locations = '{}', classes = '{class com.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/app', contextLoader = 'org.springframework.test.context.web.WebDelegatingSmartContextLoader', parent = [null]]].
failingTest(com.application.Tests)  Time elapsed: 0 sec  <<< ERROR!
java.util.ConcurrentModificationException

[Some other tests executing]

Results :

Tests in error: 
  Tests.failingTest» ConcurrentModification

I am not sure what is causing the Concurrent Modification Exception or how to avoid this issue from occurring as it only happens sometimes, but it is the same test that fails and not other tests in my test suite.

diepjy
  • 283
  • 2
  • 10
  • Maybe because your tests cannot be run in parallel and share some state? Can you show them? Can you post the full stacktrace as well? – Tunaki Nov 21 '16 at 12:58
  • I've checked that the code that is being tested does not share any state. The stacktrace is just the test being successfully run followed by other tests being run. But no where in the stacktrace mentioned concurrent modification exception besides what I have included in the stacktrace, so I don't know where it would be coming from – diepjy Nov 21 '16 at 13:47
  • The complete stacktrace is not in the console, but in the reports file. If you want it in the console, do `mvn -Dsurefire.useFile=false test`. – Tunaki Nov 21 '16 at 13:52
  • I have run the Maven build with the stacktrace but with the same stacktrace output. The only stacktrace I get back is the one I am expecting from the test (with no concurrent modification exception), but there is no stacktrace when the concurrent modification exception occurs, only the stacktrace of other tests that have run. – diepjy Nov 21 '16 at 14:44
  • Then your code isn't logging properly the error, maybe. – Tunaki Nov 21 '16 at 16:08
  • I am having exactly the same problem after upgrading to version 2.19.1. I am using TestNG for unit tests and Jacoco for coverage. – Jagger Dec 06 '16 at 08:24

2 Answers2

0

I found out the issue was occurring because of a method which I had not mocked out which was creating and running a thread (even though the thread was not modifying any resources) - so I mocked it out and the issue seems to be resolved.

diepjy
  • 283
  • 2
  • 10
0

I was having the same issue, but it was related to the change made to Collections.sort() in Java 8. More information.

Paulo Merson
  • 13,270
  • 8
  • 79
  • 72