You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:37:25