Problem Description
In a multi-module Maven project, where Module B depends on Module A (B -> A), you might encounter a compilation error when building Module B. The error, java: 程序包XXX.XXX.XXX不存在 (or "package XXX.XXX.XXX does not exist" in English), occurs if Module A relies on a local JAR file that is not visible to Module B during its compilation phase. This issue arises because Maven's dependency resolution mechanism struggles to propagate local, system-scoped dependencies across module boundaries.
Scenario
Consider a project structure where Module B depends on Module A, and Module A has a dependency on a local JAR file, for example, my-local-library.jar. The dependency in Module A's pom.xml might be configured like this:
<dependency>
<groupId>com.example</groupId>
<artifactId>my-local-library</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/my-local-library.jar</systemPath>
</dependency>
When you attempt to compile Module B, Maven may fail to find classes from my-local-library.jar, leading to the aforementioned package error. You might also see a warning in the build log:
[WARNING] The POM for com.example:my-local-library:jar:1.0 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
This warning indicates that Maven cannot properly resolve the POM for the local JAR, making its transitive dependencies unavailable to dependent modules.
Solution 1: Deploy the Local JAR to a Maven Repository
The most robust solution is to avoid using system-scoped dependencies. Instead, deploy the local JAR to a Maven repository (either your local repository or a private server).
First, ensure the JAR has a valid POM file. Then, use the maven-deploy-plugin or the deploy:deploy-file goal to upload it. For example:
mvn deploy:deploy-file \
-DgroupId=com.example \
-DartifactId=my-local-library \
-Dversion=1.0 \
-DgeneratePom=true \
-Dpackaging=jar \
-Dfile=lib/my-local-library.jar \
-Durl=file:///${project.basedir}/.m2/repository \
-DrepositoryId=local-repo
After deploying, update Module A's dependency to use the standard scope:
<dependency>
<groupId>com.example</groupId>
<artifactId>my-local-library</artifactId>
<version>1.0</version>
</dependency>
Now, run mvn clean install from the project's root directory. Maven will resolve the dependency correctly, and the compilation error in Module B should be resolved.
Solution 2: Configure the Compiler Plugin in the Dependent Module
If deploying the JAR is not feasible, you can use a workaround by configuring the maven-compiler-plugin in the dependent module (Module B). This tells the Java compiler to look for classes in the specified directory during compilation.
Add the following configuraton to Module B's pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
<compilerArguments>
<extdirs>${project.basedir}/../module-a/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</build>
The <extdirs> argument specifies an additional directory for the compiler to search for JAR files. This allows Module B's compiler to find the classes from the local JAR used by Module A, resolving the compilation error. Note that this is a build-time solution and does not make the dependency available at runtime in the same way a proper Maven dependency would.