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

如何通过Java Web Start(JNLP)启动Spring Boot API JAR包?

问题描述

尝试通过JNLP启动包含Spring Boot API的JAR包时,抛出以下异常:

java.lang.IllegalStateException: Unable to determine code source archive from \\localhost:8080\webstart\printer-api\printer-api.jar
at org.springframework.boot.loader.Launcher.createArchive(Launcher.java:126)
at org.springframework.boot.loader.ExecutableArchiveLauncher.<init>(ExecutableArchiveLauncher.java:38)
at org.springframework.boot.loader.JarLauncher.<init>(JarLauncher.java:35)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)

使用的JNLP文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://localhost:8080/webstart/printer-api" href="printer-api.jnlp">
    <information>
        <title>PrinterAPi</title>
        <vendor>ADM</vendor>
        <homepage href="http://localhost:8080/webstart/printer-api"/>
        <description>Web Start</description>
        <offline-allowed/>
    </information>
    <security>
        <all-permissions/>
    </security>
    <resources>
        <j2se version="1.8+"  href="http://java.sun.com/products/autodl/j2se"/>
        <jar href="printer-api.jar" />
    </resources>
    <application-desc main-class="org.springframework.boot.loader.JarLauncher" />
</jnlp>

已查阅相关问题但未获得明确解决方案,现寻求通过Java Web Start/JNLP启动Spring Boot API JAR包的可行方案。

可行解决方案

方案1:改用普通JAR替代Spring Boot可执行JAR

Spring Boot默认生成的可执行JAR带特殊加载逻辑,和JNLP的代码源处理逻辑冲突。调整打包配置生成普通JAR,同时单独处理依赖:

  • 在pom.xml里给spring-boot-maven-plugin添加classifier参数,生成普通JAR:
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <classifier>exec</classifier>
    </configuration>
</plugin>
  • 执行打包后会得到两个文件:printer-api.jar(包含业务代码的普通JAR)和printer-api-exec.jar(原可执行JAR)
  • 修改JNLP的main-class为你的Spring Boot应用主类(比如com.example.PrinterApiApplication),并把所有依赖JAR添加到<resources>的<jar>标签里(可用Maven的dependency:copy-dependencies命令把依赖批量复制到webstart目录)

方案2:自定义启动器适配JNLP路径格式

异常显示JNLP把JAR路径转成了UNC格式(\\localhost...),Spring Boot的JarLauncher无法识别这种格式,自定义启动类处理:

  1. 写一个继承JarLauncher的自定义启动类,重写createArchive方法适配UNC路径:
public class JnlpJarLauncher extends JarLauncher {
    @Override
    protected Archive createArchive() throws Exception {
        CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
        if (codeSource != null) {
            URL location = codeSource.getLocation();
            // 把UNC路径转成合法的file URL格式
            String path = location.getPath();
            if (path.startsWith("\\\\")) {
                path = "file:///" + path.replace("\\", "/");
                location = new URL(path);
            }
            return createArchive(location);
        }
        throw new IllegalStateException("Unable to determine code source archive");
    }

    public static void main(String[] args) throws Exception {
        new JnlpJarLauncher().launch(args);
    }
}
  1. 把这个类放进项目,打包到Spring Boot可执行JAR里
  2. 修改JNLP的main-class为这个自定义类的全限定名(比如com.example.JnlpJarLauncher)

方案3:调整JNLP的路径配置

修改JNLP文件的codebase和JAR引用格式,确保路径被正确解析:

  • 把codebase改成jnlp://localhost:8080/webstart/printer-api/(注意结尾加斜杠)
  • 或者给jar标签使用绝对URL:
<resources>
    <j2se version="1.8+"  href="http://java.sun.com/products/autodl/j2se"/>
    <jar href="http://localhost:8080/webstart/printer-api/printer-api.jar" />
</resources>
  • 同时确保服务器配置了正确的MIME类型:添加application/x-java-jnlp-file对应.jnlp后缀

方案4:用JNLP扩展机制拆分依赖

把Spring Boot的依赖打包成独立的JNLP扩展,避免和主JAR的加载逻辑冲突:

  1. 写一个扩展JNLP文件(比如spring-boot-deps.jnlp),里面列出所有Spring Boot依赖JAR
  2. 在主JNLP里引入这个扩展:
<resources>
    <j2se version="1.8+"  href="http://java.sun.com/products/autodl/j2se"/>
    <extension name="spring-boot-deps" href="spring-boot-deps.jnlp"/>
    <jar href="printer-api.jar" />
</resources>
  1. 主JAR用普通JAR格式,main-class设置为你的Spring Boot应用主类

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:27:19