Maven项目如何添加module-info.java并发布Java 8和Java 17双版本
兼容多Java版本的类库改造配置方案
一、添加兼容Java 8的module-info.java
Java 8本身不识别模块系统语法,直接把module-info.java放到普通源码目录会导致编译失败,这里采用JDK 9引入的多版本JAR(Multi-Release JAR) 特性实现兼容:Java 8环境会自动忽略JAR包中META-INF/versions目录下的内容,Java 9+环境则可以正常读取该目录下的模块声明。
操作步骤:
- 在项目中新建独立的Java 9+源码目录:
src/main/java9 - 在该目录下编写正常的
module-info.java,示例如下:
module com.yourorg.my.lib { // 对外导出的包 exports com.yourorg.my.lib.publicapi; // 声明依赖的其他模块 requires java.base; }
- 不要将
module-info.java放到src/main/java目录下,避免Java 8编译器报错。
二、Maven配置方案
可以根据需求选择两种实现方式,没有Java 17专属代码的话优先选第一种。
方案1:发布单个多版本JAR(推荐)
单个JAR包同时兼容Java 8和Java 9+环境,用户无需区分依赖版本,使用成本最低。
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <executions> <!-- 编译普通业务代码为Java 8兼容版本 --> <execution> <id>default-compile</id> <goals> <goal>compile</goal> </goals> <configuration> <source>8</source> <target>8</target> <release>8</release> </configuration> </execution> <!-- 单独编译module-info.java为Java 9版本 --> <execution> <id>compile-java9-module</id> <goals> <goal>compile</goal> </goals> <configuration> <source>9</source> <target>9</target> <release>9</release> <compileSourceRoots> <compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot> </compileSourceRoots> <multiReleaseOutput>true</multiReleaseOutput> </configuration> </execution> </executions> </plugin> <!-- 打包时声明为多版本JAR --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifestEntries> <Multi-Release>true</Multi-Release> </manifestEntries> </archive> </configuration> </plugin> </plugins> </build>
直接执行mvn clean deploy即可发布通用版本。
方案2:分别发布Java 8、Java 17两个独立版本
如果你的代码中包含Java 17专属的优化或API,可以通过分类器(classifier)区分两个版本:
<profiles> <!-- 默认激活Java 8版本配置 --> <profile> <id>java8</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <maven.compiler.release>8</maven.compiler.release> <jar.classifier>jdk8</jar.classifier> </properties> </profile> <!-- Java 17版本配置 --> <profile> <id>java17</id> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <maven.compiler.release>17</maven.compiler.release> <jar.classifier>jdk17</jar.classifier> </properties> <build> <resources> <resource> <directory>src/main/java9</directory> <targetPath>META-INF/versions/9</targetPath> </resource> </resources> </build> </profile> </profiles> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <classifier>${jar.classifier}</classifier> </configuration> </plugin> </plugins> </build>
发布时分别执行两次命令即可:
- 发布Java 8版本:
mvn clean deploy -P java8 - 发布Java 17版本:
mvn clean deploy -P java17
用户引入依赖时按需选择分类器即可:
<!-- Java 8版本依赖 --> <dependency> <groupId>com.yourorg</groupId> <artifactId>my-lib</artifactId> <version>0.3</version> <classifier>jdk8</classifier> </dependency> <!-- Java 17版本依赖 --> <dependency> <groupId>com.yourorg</groupId> <artifactId>my-lib</artifactId> <version>0.3</version> <classifier>jdk17</classifier> </dependency>
版本依赖适配
你现有的版本依赖逻辑可以完全保留:
- 0.2及更早版本只提供Java 8兼容的无模块支持包
- 0.3版本采用上述配置后,不需要拆分
my-mod和my-lib两个独立项目,单个版本即可同时满足Java 8旧客户端和Java 17+新客户端的使用需求。如果确有拆分需求,my-mod直接依赖my-lib:0.3添加自身的模块配置即可。
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

