Keywords: Java Module System | Eclipse Error | Package Conflict | JPMS | Classpath Management
Abstract: This paper provides an in-depth analysis of the 'package accessible from more than one module' error in Java 9+ module systems, detailing the conflict mechanisms between JPMS module path and classpath, and offers comprehensive solutions ranging from compiler compatibility settings to JAR reconstruction with practical code examples.
Problem Background and Phenomenon
In Java development environments using Eclipse IDE with JDK 10 or later, developers may encounter error messages such as: The package java.awt is accessible from more than one module: <unnamed>, java.desktop. This typically occurs when projects reference third-party JAR files containing standard Java packages like javax.swing or java.awt.
Root Cause Analysis
The core issue lies in the package visibility rules of the Java Platform Module System (JPMS). Since the introduction of modules in Java 9, it is prohibited for the same package to be exported by multiple modules simultaneously. Specifically in this scenario:
- System library modules (e.g.,
java.desktop) export standard packages via the module path - Third-party JAR files on the classpath have their contents assigned to the unnamed module (<unnamed>)
- When both locations contain packages with identical names, they violate JPMS's single-module export principle
Code Example and Reproduction
The following example code demonstrates a typical problem scenario:
package test;
import javax.swing.JDialog;
public class Test {
public static void main(String[] args) {
new JDialog();
}
}
When a JAR file containing the javax/swing directory structure exists on the classpath, even if the JAR contains no actual class files, it will trigger the module conflict error.
Detailed Solutions
Temporary Solution: Compiler Compatibility Settings
Setting the compiler compliance level to Java 8 can temporarily avoid this issue since Java 8 and earlier versions do not use the module system:
// Set Compiler compliance level: 1.8 in Eclipse project properties
Fundamental Solution: JAR File Reconstruction
Long-term solutions require modifying conflicting JAR files:
- When Source Code is Available: Rename conflicting packages, for example changing
javatojava_utilandjavaxtojavax_util - When Only Class Files are Available: Obtain source code through decompilation tools, modify package names, and recompile
Dependency Management Solution
For Maven projects, the issue can be resolved by excluding conflicting dependencies:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.24.1</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
Diagnostic Techniques
Using Eclipse's Ctrl + Shift + T shortcut to open the type search dialog and entering the conflicting package name can quickly locate all JAR files containing that package. Expanding the "Projects and External Dependencies" node in Package Explorer provides a visual representation of dependency relationships.
Practical Application Case
During the migration of a large legacy project, the author encountered dozens of outdated dependency libraries. Through systematic identification and removal of conflicting dependencies, the project was successfully converted to a standard Maven structure. Although this process was time-consuming, it ensured long-term maintainability of the project.
Technical Evolution Context
The introduction of the Java module system addresses long-standing issues of JAR hell and classpath pollution. While presenting short-term migration challenges, it ultimately enhances application reliability and security. Developers should follow best practices and avoid using Java standard package names in custom code.