如何在 JavaFX 21 模块化应用程序中使用 JLink(以便打包为本机可执行文件),
将自动模块 H2 和 Hibernate 放在类路径中,如本视频中所述,
有相应的代码示例吗?
我尝试在资源中添加2个jar,并将相应的requires module-info更改为static:
我的模块信息:
module module-name {
requires static com.h2database;
requires static org.hibernate.orm.core;
opens package-name.model to org.hibernate.orm.core;
opens package-name.interfaces to org.hibernate.orm.core;
}
我想了解如何使用模块化应用程序中的类路径来管理与自动模块相关的问题。
谢谢@jewelsea
当我删除需要并打开时,休眠不可见并且构建失败。
我正在使用 Maven,我的 jpackage 命令是:
jpackage --dest output --name %1 --type msi --module-path "%PATH_TO_FX_JMODS%;./target/%jarName%" --add-modules %4 --module %5 --win-shortcut --win-menu --win-menu-group %1 --java-options -Xmx2048m --vendor %3 --copyright "Copyright © %year% %3" --icon src/main/resources/package-name/images/icon.ico --app-version %2
更新以解决问题编辑
创建此答案后,编辑了问题以注意到开发人员使用的是 jpackage 而不是 jlink。
jpackage 和 jlink 之间的一个关键区别是,使用 jpackage 时处理非模块化依赖关系的方式与使用 jlink 处理问题的方式不同(因为 jlink 无法处理自动模块依赖关系,但 jpackage 是能够处理非模块化依赖项)。
原始答案仍然特定于使用放置在类路径而不是模块路径上的软件库的技术在jlink链接了运行时所需的模块之后。
但是,如果您要将 jpackage 与不完全模块化的软件一起使用,我不建议您将项目模块化。删除模块信息并按照 openjfx.io 入门文档中非模块化应用程序和运行时的说明进行操作。 jpackage 可以很好地处理打包非模块化应用程序,但如何为您的特定应用程序和构建结构执行此操作的完整描述超出了我在此讨论的范围。
如果自动模块的 jar 文件位于类路径而不是模块路径上,则它们不是自动模块,它们只是从类路径加载的类。因此,它们不应在模块信息中作为模块引用,也不应作为命令行参数引用的模块。
发展
开发时,应确保所需的软件(不是正确模块的库)位于类路径中。一般来说,Maven、Gradle 等与 IDE 集成的工具会自动确保这一点。
包装
构建部署包时,您应该包含要放置在发行版中的类路径上的 jar 文件(例如使用 Maven 组装工具)。您可以将它们放置在程序集创建的 lib 目录中。该程序集可以压缩 jlink 映像中的所有内容(例如,由 javafx-maven-plugin 创建的 javafx 映像),包括要放置在类路径上的库。
运行时
用于启动应用程序的脚本需要将参数添加到 java 命令,以在运行时找到 lib 目录中的 lib 文件并将它们放在类路径中(例如
java -cp lib
)。所需的 VM 选项可以通过 javafx-maven-plugin jlink 配置中 <options>
元素的 <launcher>
元素指定。
如果你使用 Gradle,badass jlink 插件会做一些奇怪的事情(例如重新打包软件和创建假模块信息),以允许自动模块转换为可以通过 jlink 链接的实际模块。它并不适用于所有软件,但如果您想使用它,可能适合您。如果您需要更多信息,请阅读(非常复杂的)badass jlink 插件说明。
Moditect for Maven
诸如 moditect 之类的工具可用于 Maven,它们可以完成与 badass jlink 插件类似的任务,但以更手动的方式完成。 Moditect 不是我推荐的工具,但如果您想使用它,它是一个选择。
考虑一下用jpackage代替jlink是否会更好。 jpackage 对于处理非模块化软件(包括自动模块)的打包有特定的参数。