Java 9迁移Web应用时出现primefaces模块未找到问题求助
我帮你梳理下这个问题的根源和解决办法——这在Java 9+迁移旧版非模块化依赖时是很常见的情况。
问题根源
PrimeFaces 6.0是Java 9发布前的版本(2016年发布,Java 9于2017年推出),它的JAR包里没有module-info.class,不属于显式模块化JAR。在Java 9的模块系统中,这类依赖会被当作自动模块处理,但如果Maven或IDE没有正确把它放到模块路径上,就会抛出module not found: primefaces的错误。
分步解决方案
1. 先确认自动模块名(确保没写错)
虽然你写的requires primefaces;大概率是对的,但我们可以用命令验证:
- 找到本地Maven仓库里PrimeFaces 6.0的JAR路径(一般是
~/.m2/repository/org/primefaces/primefaces/6.0/primefaces-6.0.jar) - 打开终端执行:
jar --file=primefaces-6.0.jar --describe-module
你会看到类似这样的输出:
No module descriptor found. Derived automatic module. primefaces@6.0 automatic requires java.base mandated contains org.primefaces contains org.primefaces.abac ...
这里的primefaces就是正确的自动模块名,说明你module-info.java里的写法没问题,问题出在依赖路径配置。
2. 配置Maven把依赖放到模块路径
Java 9+的模块化项目需要将依赖放在模块路径(而非传统的classpath)上。你可以在pom.xml中添加maven-compiler-plugin的配置来实现:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <!-- 务必用支持Java 9的版本 --> <configuration> <release>9</release> <compilerArgs> <arg>--module-path</arg> <arg>${project.build.directory}/dependency-jars</arg> <!-- 强制JVM识别自动模块 --> <arg>--add-modules</arg> <arg>primefaces</arg> </compilerArgs> </configuration> <executions> <execution> <id>copy-dependencies</id> <phase>compile</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/dependency-jars</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
这个配置会把所有依赖JAR复制到target/dependency-jars目录,编译时将该目录作为模块路径,并强制JVM识别primefaces自动模块。
3. 检查IntelliJ的模块依赖配置
有时候IDE不会自动把依赖加到模块路径,需要手动调整:
- 打开
File > Project Structure > Modules - 选中你的
sharedwebapp模块,切换到Dependencies标签页 - 找到PrimeFaces的依赖项,检查它的
Scope是Compile,并且右侧的Module列显示的是Module(不是Classpath) - 如果是
Classpath,点击下拉菜单改成Module,然后点Apply和OK
4. 额外提示:兼容性问题
如果解决了模块找不到的问题后,出现JDK内部API访问的错误(比如sun.misc.Unsafe相关),你可能需要在编译参数里添加--add-opens或--add-exports,比如:
<arg>--add-opens=java.base/java.lang=primefaces</arg>
不过这是后续的兼容性问题,先解决当前的模块找不到问题即可。
内容的提问来源于stack exchange,提问作者jahuer1

