使用 Spring Boot 和 Java Web Start (JNLP) 时出现异常

Exception when using Spring Boot and Java Web Start (JNLP)

我正在使用 Spring Boot 构建应用程序。我把它打包成一个可执行的jar。我想使用 Java Web Start 部署此应用程序。我写了一个 JNLP 文件,但是当我尝试 运行 它时,我得到了他以下的异常:

java.lang.IllegalStateException: Unable to determine code source archive from \localhost\printpoc.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)
at java.lang.Thread.run(Unknown Source)

这是我的 JNLP 文件:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://localhost/" href="printpoc.jnlp">
<information>
    <vendor>Me</vendor>
    <homepage href="http://localhost/" />
    <description>PrintPoc</description>
</information>
<security>
    <all-permissions/>
</security>
<resources>
    <j2se version="1.8+" />
    <jar href="printpoc.jar" />
</resources>
<application-desc main-class="org.springframework.boot.loader.JarLauncher" />

我想尝试 ,但是布局模块已经不存在了。我尝试了 ZIP、NONE 等,仍然没有成功。 这是我的 pom.xml :

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <layout>JAR</layout>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

你能帮帮我吗?

这在我看来像是一个 Spring 错误。来自 source:

ProtectionDomain protectionDomain = getClass().getProtectionDomain();
CodeSource codeSource = protectionDomain.getCodeSource();
URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null;
String path = (location != null) ? location.getSchemeSpecificPart() : null;

if (path == null) {
    throw new IllegalStateException("Unable to determine code source archive");
}

File root = new File(path);
if (!root.exists()) {
    throw new IllegalStateException(
            "Unable to determine code source archive from " + root);
}

问题出在这一行:

String path = (location != null) ? location.getSchemeSpecificPart() : null;

来自URI documentation

At the highest level a URI reference (hereinafter simply "URI") in string form has the syntax

[scheme:]scheme-specific-part[#fragment]

因此,在 URI http://localhost/printpoc.jnlp 中,特定于方案的部分是 //localhost/printpoc.jnlp。 Spring 然后尝试将其视为一个文件名,该文件名当然不存在,这就是您看到异常的原因。

Spring 代码不正确。它错误地假设您可以从任何 URI 中创建文件名。只有 file: 个 URI 可以安全地转换为文件名,使用 new File(location) or Paths.get(location).

即可正确完成

我不确定解决方案是什么。 Spring 引导启动程序似乎假定 .jar 始终是本地文件。我怀疑它能否处理通过 HTTP 获取的 .jar 文件。