【问题标题】:Exception when using Spring Boot and Java Web Start (JNLP)使用 Spring Boot 和 Java Web Start (JNLP) 时出现异常
【发布时间】:2019-02-17 04:55:02
【问题描述】:

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

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" />

我想试试that,但是布局 MODULE 已经不存在了。我尝试使用 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>

你能帮帮我吗?

【问题讨论】:

    标签: java spring spring-boot java-web-start jnlp


    【解决方案1】:

    在我看来,这就像一个 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

    在最高级别,字符串形式的 URI 引用(以下简称“URI”)具有以下语法

    [方案:]方案特定部分[#片段]

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

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

    我不确定解决方案是什么。 Spring Boot 启动器似乎假设 .jar 始终是本地文件。我怀疑它可以与通过 HTTP 获得的 .jar 文件一起使用。

    【讨论】:

    • 所以我想用自定义 LayoutFactory 重现 MODULE 布局的行为也行不通。创建一个包含我的 Spring boot jar 的 Jar 怎么样?第一个将通过 Java Web Start 下载和提取,然后将启动第二个(spring boot )。这听起来像是一件可行的事情吗?
    • 这可能行得通。您的 Web Start 程序可能想要执行类似 Path jar = Files.createTempFile(null, ".jar"); try (InputStream embeddedJar = getClass().getResourceAsStream("springboot.jar")) { Files.copy(embeddedJar, jar, REPLACE_EXISTING); } 的操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 2016-07-24
    • 2016-06-26
    相关资源
    最近更新 更多