如何通过 jpackage 正确打包 JavaFX + Spring Boot 应用程序?

How to package JavaFX + Spring Boot application via jpackage correctly?

我在使用 badass jlink 插件的 jpackage 打包我的项目时遇到问题。项目包含 Spring Boot,它通过 FXVeawerJavaFX 一起工作。 Spring Data 应用程序与数据库一起工作。

我的build.gradle:

plugins {
id 'org.springframework.boot' version '2.6.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.10'
id 'org.beryx.jlink' version '2.24.1'
}

group = 'spring.geodemo'
version = '0.1.7'
sourceCompatibility = '17'


application {
mainModule = 'spring.geodemo'
mainClass = 'spring.geodemo.GeoDemoApplication'
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter'

implementation 'javax.servlet:javax.servlet-api:4.0.1'
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.2'


implementation group: 'org.springframework', name: 'spring-jdbc', version: '5.3.16'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', 
version: '2.6.3'
implementation group: 'org.springframework', name: 'spring-core', version: '5.3.16'

implementation group: 'io.projectreactor.tools', name: 'blockhound', version: 
'1.0.6.RELEASE'


testImplementation 'org.springframework.boot:spring-boot-starter-test'

implementation 'net.rgielen:javafx-weaver-spring-boot-starter:1.3.0'
implementation 'org.postgresql:postgresql:42.3.1'
}

javafx {
version = '17.0.1'
modules = ['javafx.controls', 'javafx.fxml']
}

jlink {
imageZip = 
project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip")
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
launcher {
    name = 'Geo'
}

jpackage {
    forceMerge('log4j-api')
}
}

应用程序正在打包,但由于错误 Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.IllegalAccessException-->module spring.geodemo does not open spring.geodemo to unnamed module @39cd0bac 没有启动。

我不知道 unnamed module @39cd0bac 出现的原因。

源代码:on GitHub

解释错误

Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.IllegalAccessException
  module spring.geodemo does not open spring.geodemo to unnamed module @39cd0bac

cglib 被 spring 用于字节码操作以支持核心 spring 任务,如依赖注入。这需要模块化应用程序中的访问权限。 cglib 在 class 路径上 运行 并试图在模块路径上的模块中操作字节代码。在您当前的运行时配置下,此类访问受到限制且不允许。

您目前无法使用jlink

Spring boot 当前没有为使用 jlink 的模块化构建配置,这在 spring boot 3 发布之前不会发生。

因此您需要将您的应用程序打包为非模块化应用程序,它运行在 class 路径之外,并且 spring 库也应该在 class 路径上。 JavaFX 库应该在模块路径上。

要创建这样的构建,请不要使用 badass-jlink-plugin,因为 jlink 假定所有内容都是定义良好且非自动的模块。所以这不适用于 spring boot 2,它目前依赖于自动模块。

改用运行时插件和非模块化应用程序

您的非模块化应用程序将位于 class 路径上,spring 依赖库(如 cglib)也将位于 class 路径上,因此不会出现访问错误。

当你使用gradle和jpackage时,使用badass-runtime-plugin,它可以使用jpackage来打包非模块化应用程序。

阅读、理解并应用其复杂的文档。

查看示例项目,尤其是使用它的 JavaFX 应用程序示例,这些示例在其 github site

中列出

完整记录此过程超出了 Whosebug 答案的范围。