使用maven-assembly-plugin构建带外部配置文件的可执行Fat Jar
嘿,这个需求我熟!刚好帮你梳理下Maven配置和代码调整的完整步骤,确保配置文件能乖乖待在Jar外面,程序还能正确读取到它:
第一步:调整Maven配置,分离配置文件
我们需要通过Maven插件实现两个核心目标:把配置文件复制到Jar同目录,同时不让配置文件打包进Jar内部。
1. 配置maven-resources-plugin,复制配置文件到输出目录
这个插件会把你src/main/resources下的配置文件,复制到Maven构建的target目录(也就是最终Jar所在的目录)。在pom.xml的<build>节点里添加:
<resources> <!-- 复制目标配置文件到target目录,和Jar同层级 --> <resource> <directory>src/main/resources</directory> <includes> <include>*.properties</include> <!-- 替换成你的配置文件类型/具体名称 --> <include>*.yml</include> <include>*.xml</include> </includes> <targetPath>${project.build.directory}</targetPath> <filtering>false</filtering> <!-- 不需要变量替换就设为false,需要的话改成true --> </resource> <!-- 保留其他资源打包进Jar(如果有需要的话) --> <resource> <directory>src/main/resources</directory> <excludes> <exclude>*.properties</exclude> <exclude>*.yml</exclude> <exclude>*.xml</exclude> </excludes> </resource> </resources>
2. 配置maven-jar-plugin,排除Jar内的配置文件
确保最终生成的Jar里不包含这些配置文件,避免和外部文件冲突:
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <excludes> <exclude>*.properties</exclude> <exclude>*.yml</exclude> <exclude>*.xml</exclude> </excludes> <!-- 可选:设置主类,方便直接用java -jar运行 --> <archive> <manifest> <mainClass>com.yourpackage.YourMainClass</mainClass> </manifest> </archive> </configuration> </plugin> </plugins>
3. 可选:用maven-assembly-plugin构建分发包(方便部署)
如果你想生成一个包含Jar和配置文件的压缩包,方便直接解压部署,就加上这个插件:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> <!-- 打包成包含依赖的Fat Jar --> </descriptorRefs> <archive> <manifest> <mainClass>com.yourpackage.YourMainClass</mainClass> </manifest> </archive> <appendAssemblyId>false</appendAssemblyId> <!-- 去掉默认的assembly后缀 --> <!-- 把target下的配置文件包含到分发包根目录 --> <files> <file> <source>${project.build.directory}/config.properties</source> <!-- 替换成你的配置文件名 --> <outputDirectory>/</outputDirectory> </file> <file> <source>${project.build.directory}/application.yml</source> <outputDirectory>/</outputDirectory> </file> </files> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
第二步:修改Java代码,优先读取外部配置文件
程序运行时,我们要先检查Jar同目录下的配置文件是否存在,存在就用外部的;如果没有(比如调试阶段),可以 fallback 到Jar内部的配置(当然你也可以直接抛出异常,完全按照你的设计需求来)。
以读取properties文件为例,代码示例:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ConfigLoader { // 替换成你的配置文件名 private static final String CONFIG_FILE = "config.properties"; public static Properties loadConfig() throws IOException { Properties configProps = new Properties(); // 先尝试读取Jar同目录的外部配置文件 File externalConfig = new File(CONFIG_FILE); if (externalConfig.exists() && externalConfig.isFile()) { try (InputStream is = new FileInputStream(externalConfig)) { configProps.load(is); System.out.println("✅ 成功加载外部配置文件:" + externalConfig.getAbsolutePath()); } } else { // 可选:如果外部没有,加载Jar内部的配置作为备用 try (InputStream is = ConfigLoader.class.getClassLoader().getResourceAsStream(CONFIG_FILE)) { if (is != null) { configProps.load(is); System.out.println("ℹ️ 未找到外部配置,加载Jar内部默认配置"); } else { throw new IOException("❌ 配置文件不存在:" + CONFIG_FILE); } } } return configProps; } }
最后验证一下
运行mvn clean package后,去target目录看看:
- 生成的Jar包里没有配置文件(可以用解压工具打开验证)
target目录下有单独的配置文件- 如果用了Assembly插件,会生成一个包含Jar和配置文件的压缩包,解压后两者在同一目录
这样部署的时候,直接修改Jar同目录的配置文件就行,不用重新打包Jar啦!
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

