I am working on a project that includes both Gradle and Maven subprojects. Until yesterday I was using Eclipse 2020-03, but I updated to 2021-03 and now I can't run any tests. I haven't changed anything to the project's configuration, junit 5.6.0 is included both in pom.xml and build.gradle.
Now whenever I try to run a test, I get this error:
java.lang.NoClassDefFoundError: org/junit/platform/commons/util/ClassNamePatternFilterUtils
at org.junit.platform.launcher.core.LauncherFactory.loadAndFilterTestExecutionListeners(LauncherFactory.java:122)
at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:108)
at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:75)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.<init>(JUnit5TestLoader.java:34)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.lang.Class.newInstance(Class.java:584)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createRawTestLoader(RemoteTestRunner.java:371)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createLoader(RemoteTestRunner.java:366)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.defaultInit(RemoteTestRunner.java:310)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.init(RemoteTestRunner.java:225)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.lang.ClassNotFoundException: org.junit.platform.commons.util.ClassNamePatternFilterUtils
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 14 more
When I add Junit 5 manually to the project's build path, as suggested by a lot of similar questions here, I get this in the Add Library Window:
Current Location: org.junit.jupiter.api_5.7.1.v20210222-1948.jar - /Users/user/.p2/pool/plugins
But even then, when I add it, I get that junit launcher was not found, followed by:
java.lang.SecurityException: class "org.junit.platform.commons.util.ClassNamePatternFilterUtils"'s signer information does not match signer information of other classes in the same package
Note that in 2020-03, the project's build path did not include explicitly Junit 5 (hadn't added it manually). The same tests also work there as intended, both in Maven and Gradle projects.
I have also tried deleting anything related to the previous eclipse installations (~/Library related contents)
My .classpath is the following:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry combineaccessrules="false" kind="src" path="/com.myproject.businesslayer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
The relevant part of my root pom.xml :
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<tycho-version>1.7.0</tycho-version>
<mockito-version>3.3.0</mockito-version>
<hamcrest-version>2.1</hamcrest-version>
<archunit-version>0.11.0</archunit-version>
<junit-version>5.6.0</junit-version>
<xmlunit-version>2.6.3</xmlunit-version>
<!-- plugin versions -->
<compiler-plugin-version>3.8.0</compiler-plugin-version>
<groovy-eclipse-compiler-version>3.4.0-01</groovy-eclipse-compiler-version>
<jar-plugin-version>3.1.2</jar-plugin-version>
<surefire-plugin-version>2.22.2</surefire-plugin-version>
<versions-plugin-version>2.7</versions-plugin-version>
<jacoco-plugin-version>0.8.4</jacoco-plugin-version>
<sonar-plugin-version>3.8</sonar-plugin-version>
<groovy-eclipse-batch-version>2.5.8-01</groovy-eclipse-batch-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
...
</modules>
<build>
<defaultGoal>verify</defaultGoal>
<!-- only relevant for modules containing plain java tests -->
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin-version}</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<configuration>
<includes>
<include>**/*.java</include>
</includes>
<excludedGroups>PluginTest</excludedGroups>
</configuration>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<!-- only for plain java test execution -->
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5-api</artifactId>
<version>${archunit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5-engine</artifactId>
<version>${archunit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>${hamcrest-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${org.assertj}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
and of my root build.gradle:
plugins {
...
}
subprojects { sub ->
apply plugin: 'java'
sourceCompatibility = 11
targetCompatibility = 11
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(Test) {
...
}
dependencies {
testCompile "org.assertj:assertj-core:${assertJVersion}"
testCompile "org.junit.jupiter:junit-jupiter-api:${jUnitVersion}"
testRuntime "org.junit.jupiter:junit-jupiter-engine:${jUnitVersion}"
testCompile "org.junit.jupiter:junit-jupiter-params:${jUnitVersion}"
testCompile "org.mockito:mockito-core:${mockitoVersion}"
testCompile "org.hamcrest:hamcrest:${hamcrestVersion}"
testCompile "org.slf4j:slf4j-simple:${slf4jVersion}"
testCompile "com.tngtech.archunit:archunit-junit5-api:${archUnitVersion}"
testRuntime "com.tngtech.archunit:archunit-junit5-engine:${archUnitVersion}"
}
test {
useJUnitPlatform()
finalizedBy jacocoTestReport
}
jacocoTestReport {
dependsOn test
}
repositories {
mavenLocal()
jcenter()
maven {
url "${nexusUrl}"
}
}
}
wrapper {
gradleVersion = '5.6'
}
and in gradle.properties:
hamcrestVersion=2.1
jUnitVersion=5.6.0
archUnitVersion=0.11.0
The problem is solved if I update the JUnit version both for Maven and Gradle to 5.7.1.
This still does not answer the question why it was working on older Eclipse installations, of course.