如何通过 jpackage 正确打包 JavaFX + Spring Boot 应用程序?
How to package JavaFX + Spring Boot application via jpackage correctly?
我在使用 badass jlink 插件的 jpackage 打包我的项目时遇到问题。项目包含 Spring Boot
,它通过 FXVeawer
与 JavaFX
一起工作。 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 答案的范围。
我在使用 badass jlink 插件的 jpackage 打包我的项目时遇到问题。项目包含 Spring Boot
,它通过 FXVeawer
与 JavaFX
一起工作。 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 答案的范围。