Keywords: Eclipse | JUnit 5 | NoClassDefFoundError | LauncherFactory | Java 9 | Module System | Testing Framework
Abstract: This paper provides a comprehensive technical analysis of the NoClassDefFoundError for LauncherFactory issue encountered when using JUnit 5 in Eclipse Oxygen 1.a. Through systematic investigation, we identify the root cause as Eclipse bug 525948 and present multiple effective solutions including separate test project architecture, proper dependency management, and correct build path configuration. The article includes detailed code examples and step-by-step configuration guidelines for developers.
Problem Context and Technical Analysis
When using Eclipse Oxygen 1.a integrated development environment with JUnit 5 framework for Java 9 project testing, developers frequently encounter a perplexing issue: Eclipse fails to recognize any test methods, displaying only "(all methods)" option in run configurations. Console output reveals the critical exception: java.lang.NoClassDefFoundError: org/junit/platform/launcher/core/LauncherFactory, indicating that the JUnit platform launcher core class cannot be properly loaded.
Root Cause Investigation
Through in-depth technical analysis, this issue has been identified as a known defect in the Eclipse platform, specifically corresponding to Eclipse bug 525948. This defect is particularly evident in Eclipse Oxygen.1a version, primarily affecting the integration between JUnit 5 and Java 9 module system. When projects contain module-info.java files, Eclipse's test runner encounters classpath resolution errors while loading the JUnit platform launcher.
From an architectural perspective, JUnit 5 introduces a completely new testing platform architecture where the LauncherFactory class serves as the core component for test discovery and execution. In the standard JUnit 5 architecture, the test execution flow proceeds as follows:
// Core JUnit 5 test execution flow
public class JUnit5TestExecutor {
public void executeTests(Class<?> testClass) {
// Create test launcher
Launcher launcher = LauncherFactory.create();
// Build test request
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder
.request()
.selectors(selectClass(testClass))
.build();
// Execute tests
TestPlan testPlan = launcher.discover(request);
launcher.execute(testPlan);
}
}
Primary Solution Strategies
Based on the technical characteristics of Eclipse bug 525948, we recommend the following validated solution approaches:
Solution 1: Separate Test Project Architecture
This represents the most stable and reliable solution, particularly suitable for production environments. Implementation steps include:
// Main project structure - includes module-info.java
src/main/java/module-info.java
src/main/java/com/example/MainClass.java
// Test project structure - excludes module-info.java
test/src/main/java/com/example/MainClassTest.java
When configuring project dependencies in Eclipse, ensure that the main project is added to the test project's module path rather than classpath. This architectural separation guarantees compatibility between the module system and testing framework.
Solution 2: Dependency Management Optimization
For projects using build tools like Maven or Gradle, ensuring complete JUnit 5 dependency chains is crucial:
// Maven configuration example
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Solution 3: Proper Build Path Configuration
When manually configuring JUnit 5 libraries in Eclipse, ensure all necessary JAR files are correctly included:
// Verify included JAR files in build path
- junit-jupiter-api-5.x.x.jar
- junit-jupiter-engine-5.x.x.jar
- junit-platform-commons-1.x.x.jar
- junit-platform-engine-1.x.x.jar
- junit-platform-launcher-1.x.x.jar
- opentest4j-1.x.x.jar
Supplementary Solutions and Best Practices
Beyond the primary solutions, several supplementary approaches and best practices deserve attention:
Correct Import Statement Usage
Ensure proper import statements for JUnit 5, avoiding confusion with JUnit 4:
// Correct - JUnit 5
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
// Incorrect - JUnit 4
import org.junit.Test;
import org.junit.Assert;
Run Configuration Adjustments
In certain scenarios, temporary run configuration adjustments can serve as quick solutions:
// In Run Configurations
- Select correct Test Runner: JUnit 5
- Verify VM parameters and classpath settings
- Ensure test classpath includes all necessary dependencies
Technical Deep Dive
From an architectural perspective, JUnit 5's modular design introduces three main components: Platform, Jupiter, and Vintage. The Platform component handles test discovery and execution, with LauncherFactory serving as the factory class for creating test launcher instances. In Java 9 module system, when main projects define explicit module boundaries, test code requires special module access permissions.
Eclipse's test runner, when processing modular projects, must properly distinguish between module path and class path. The fundamental cause of Bug 525948 lies in Eclipse's failure to correctly identify test code's module access requirements for the platform launcher classes, resulting in class loader inability to locate necessary class definitions.
Version Compatibility Considerations
It's important to note that this issue has been officially resolved in Eclipse Oxygen.3 (4.7.3) and subsequent versions. For developers still using earlier versions, the solutions presented in this paper remain effective. Additionally, we recommend monitoring version compatibility matrices between JUnit 5 and Eclipse plugins to ensure using tested version combinations.
Conclusion and Recommendations
Through systematic technical analysis and practical validation, we conclude that the JUnit 5 no tests found issue in Eclipse primarily stems from platform defects and complexities in module system integration. Adopting the separate test project architecture provides the most stable solution, while proper dependency management and build path configuration form the foundation for ensuring normal test environment operation.
For enterprise-level projects, we recommend implementing Solution 1's separate architecture, which not only resolves the current issue but also provides better engineering practices for future test maintenance and expansion. Simultaneously, continuously monitoring Eclipse and JUnit version updates and promptly upgrading to versions where this issue has been resolved represents an important measure for maintaining healthy development environments.