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

如何将WAR包嵌入可运行JAR并通过setWar()方法读取?

嵌入式Jetty加载内嵌WAR包的解决方案

核心逻辑

Jetty的WebAppContext.setWar()支持读取类路径下的资源,只要把WAR包作为类资源打包进可运行JAR,就能通过类加载器获取其路径,实现无外部依赖运行。

一、调整项目结构与Maven配置

1. 放置WAR包

将jersey-servlet.war放到项目的src/main/resources目录(没有就新建),Maven打包时会自动把它加入类路径根目录。

2. 用maven-shade-plugin打包

放弃maven-assembly-plugin,改用maven-shade-plugin处理内嵌资源和依赖,避免类冲突。在pom.xml中添加:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.5.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <!-- 指定主类,让JAR可直接运行 -->
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>你的包路径.Main</mainClass>
                            </transformer>
                        </transformers>
                        <!-- 排除签名文件,避免打包冲突 -->
                        <filters>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.SF</exclude>
                                    <exclude>META-INF/*.DSA</exclude>
                                    <exclude>META-INF/*.RSA</exclude>
                                </excludes>
                            </filter>
                        </filters>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

二、修改Java代码读取内嵌WAR

更新Main类,通过类加载器获取内嵌WAR的URL:

import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;

public class Main {
    public static void main(String[] args) {
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8088);
        server.addConnector(connector);
        WebAppContext context = new WebAppContext();
        server.setHandler(context);

        // 从类路径读取内嵌WAR
        String warUrl = Main.class.getClassLoader().getResource("jersey-servlet.war").toExternalForm();
        context.setWar(warUrl);

        try {
            server.start();
            server.join(); // 必须调用,否则主线程结束Jetty会立刻停止
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

三、打包测试

执行Maven命令打包:

mvn clean package

打包完成后,在target目录下找到生成的可运行JAR,直接用java -jar 你的JAR文件名.jar启动即可,无需外部WAR包。

常见问题

  • NullPointerException:检查WAR包是否在src/main/resources下,用jar tf 你的JAR文件名.jar查看JAR内是否包含该WAR。
  • 资源访问失败:默认WebAppContext允许类路径资源加载,无需额外配置,若有自定义配置需检查是否禁用了该功能。
  • 类冲突:确保maven-shade-plugin的过滤器排除了签名文件,上面的配置已处理此问题。

内容的提问来源于stack exchange,提问作者Dan Stone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:53:19