当前位置: 首页 > 知识库问答 >
问题:

如何在Java 11上打包具有非模块依赖关系的应用程序

公羊俊德
2023-03-14

开发并发布了一个使用Apache Batik和JavaCV的Java Swing应用程序。我已经通过java 1.6、7和8对其进行了更新。macOS、Windows和Linux的安装程序是使用Javapackager构建的。Java 8将于1月19日停止支持,我找不到一个解决方案来打包和分发新的LTS版本Java 11。

JavaCV和Batik都不生产模块化jar,但我已经成功地对它们进行了重新打包,这样我就可以在Java 11上编译并生成一个可运行的jar,这个应用程序运行得很好,但我无法将其打包分发。我曾计划使用Java 10来使用javapackager并从那里捆绑11运行时,但它使用jlink来生成自定义运行时,jlink失败了,因为JavaCV和Batik不是模块化的。JDEP不会生成模块信息。类进行修补,并使其模块化,因为Batik和JavaCV中的引用不令人满意,即使我的应用程序在没有它们的情况下运行良好。

因此,我将不得不将代码库保留在Java 8上,并将其发布,即使不再受支持。

我知道有人呼吁为javapackager创建一个替代品,但在Java 8被弃用之前,这是不会存在的。我仍然需要Batik和JavaCV项目来重构和构建模块化JAR,以生成自定义运行时。

有人能提供其他解决方案吗?我错过了什么吗?谢谢。

共有3个答案

程枫
2023-03-14

因此,唯一的解决方案是编写一个包装应用程序,使用ProcessBuilder启动原始应用程序jar。

这样做的优点是可以使用链接来生成所需的最小运行时。将jar放在bin目录中,然后使用FPM(https://github.com/jordansissel/fpm)创建安装程序。

包装器的示例代码

package xyz.arwhite.dslauncher;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DrumScoreLauncher {

    public static void main(String[] args) {
        String installHome = System.getProperty("java.home");
        String installBin = installHome + File.separator + "bin" + File.separator;

        System.out.println("Launching Drum Score Editor from "+installHome);

        List<String> cmdLine = new ArrayList<String>();
        cmdLine.add(installBin + "java");
        cmdLine.add("-jar");
        cmdLine.add(installBin + "DrumScoreEditor.jar");

        for ( int i = 0; i < args.length; i++ )
            cmdLine.add(args[i]);

        try {
            ProcessBuilder p = new ProcessBuilder(cmdLine);
            p.inheritIO();
            p.start();

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Exiting launcher");
    }

}
蔚承天
2023-03-14

这是一个指向GitHub模板的链接,展示了如何使用jlink、jpack和GitHub Actions生成JavaFX应用程序以及带有小型JVM的本机macOS、Windows和Linux安装程序:

https://github.com/wiverson/maven-jpackage-template

以下是使用Swing和嵌入式Spring Boot服务器的(WIP)版本:

https://github.com/wiverson/desktop-spring-boot

乐正嘉瑞
2023-03-14

更新:jpackage从JDK 14开始就包含在内。不过,以下答案仍然适用于较旧的JDK版本。

我也有同样的问题。我想使用JDK 11,但根据JDK-8212780,JEP 343计划用于JDK 13,所以我们需要等待更长的时间。在Java 8-10下打包“本机”自包含的应用程序不是问题,因为打包程序已经包括在内(至少在Oracle JDK中)。

今天我发现了这封电子邮件,并想试一试:您可以在github.com/skymatic/javafx11-test上看到我的示例项目,我使用JDK开发分支的反向移植的jPackager成功打包了它。

我在这里所做的:

  • 使用OpenJDK 11和OpenJFX 11创建了一个新的HelloWorld项目

当然,对于模块化项目来说更容易:在我的示例项目中,您可以看到我使用了jpackager的参数来表示模块路径和主模块,而不是classpath和main类。

 类似资料:
  • 我有一个具有多个模块的库项目,因此我将其依赖项集中在项目级build.gradle中,如下所示 我在模块中使用它作为 在我的示例应用程序(同一项目中的另一个模块)中,我将库模块作为 我试着像这样包含依赖关系 和 和 我已经试过了 如何在aar库中指定依赖项? AAR可以包括传递依赖项吗? 如果我错过了任何信息,请发表评论 提前致谢

  • 如何在node.js中卸载与dev相关的npm模块?

  • 我是和的新手。我正在尝试在远程计算机上运行hdfs MapReduce作业。我没有写入/编辑依赖项文件的权限。我想知道是否可以将我的Maven项目传递给我的MapReduce作业。这样,我就不需要SSH进入远程机器并更改maven项目的依赖关系。我将使用包含远程计算机上未包含的所有所需依赖项的JAR来运行我的MapReduce作业。

  • 我有一个Java8应用程序,它使用JavaFX,主类扩展了JavaFX.application.application。目前,我将它作为一个fat jar交付,它在Oracle Java8上运行良好。 现在我希望它能够在OpenJDK11上运行。为了添加JavaFX,我已经将org.openjfx中的工件添加到类路径中,并将它们包含在fat JAR中。如果我从命令行启动我的jar,我会得到 脏的一

  • 我无法使用ArchUnit制定以下测试: 我想确保某个包中的所有类只访问应用程序基包之外或某个子包内的类(“或”而不是“xor”)。 我得到的是: 问题是,或条件应该在onlyAccessClassesthat()中。如果一个类同时具有两种类型的访问权限,上述公式将失败,我希望这两种类型都有效。 我怎样才能实现我想要的?谢谢你在这方面的任何帮助...

  • 我有一个多模块Maven项目,其中包含子模块ModuleA和ModuleB等。ModuleA将ModuleB列为依赖项。但是,当仅构建模块A时,Maven不会解决模块B的依赖关系-导致。我想避免构建整个父级以使构建更快。目前我发现让它工作的唯一方法是使用exec插件和脚本,将父项目称为“ModuleB, ModuleA”,这意味着我必须在每次依赖项更改时更改脚本(例如添加ModuleC)。 是否有