我正在尝试做一个javafx程序,从excel文件中读取数据。我在项目中添加了poi
依赖项。
下面是我的build.gradle
文件代码。
plugins {
id 'java'
id 'application'
id 'org.javamodularity.moduleplugin' version '1.8.12'
id 'org.openjfx.javafxplugin' version '0.0.13'
id 'org.beryx.jlink' version '2.25.0'
}
group 'com'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
ext {
junitVersion = '5.9.2'
}
sourceCompatibility = '17'
targetCompatibility = '17'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
application {
mainModule = 'com.al_makkah_traders_app'
mainClass = 'com.al_makkah_traders_app.Main'
}
javafx {
version = '17.0.6'
modules = ['javafx.controls', 'javafx.fxml']
}
dependencies {
implementation 'org.controlsfx:controlsfx:11.1.2'
implementation 'org.apache.logging.log4j:log4j-core:3.0.0-alpha1'
implementation 'org.apache.poi:poi:5.2.2'
implementation 'org.apache.poi:poi-ooxml:5.2.2'
implementation 'mysql:mysql-connector-java:8.0.33'
testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}
test {
useJUnitPlatform()}
jlink {
imageZip = project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip")
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
launcher {
name = 'app'
}
}
jlinkZip {
group = 'distribution'
}
jar {
duplicatesStrategy = 'EXCLUDE'
manifest {
attributes(
'Main-Class': 'com.al_makkah_traders_app.Main'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
现在,当我尝试运行我的项目时,它会抛出一个错误,
> Task :Main.main() FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Module commons.math3 not found, required by org.apache.poi.poi
有时它会抛出一个错误,
Error occurred during initialization of boot layer
java.lang.module.FindException: Module SparseBitSet not found, required by org.apache.poi.poi.ooxml
我一直在努力解决这个问题,但我无法解决这个问题。虽然这些模块存在于我的项目中。
1条答案
按热度按时间sulc1iza1#
解决方案
使您的项目非模块化(删除
module-info.java
)。如果你需要更多的信息,请参阅openjfx.io的入门说明中关于非模块化项目的信息。特别是,您需要使用VM选项将JavaFX模块放置在模块路径上,如www.example.com说明中所述openjfx.io。
相关
您正在使用POI和Java,因此也请参考下面的问题,该问题描述了在Gradle设置中使用POI所依赖的自动模块的问题:
这是除了你的问题标题中关于commons.math3的问题之外的问题。但问题的核心仍然非常相似:commons math 3也是一个自动模块。
常见问题
本节只是按照评论中的要求解释推理。有些原因只是观点,并不是答案的核心。
为什么会出现这个问题
Understand Java modules。
你有一些模块(java模块,而不是maven或gradle模块)是你系统中依赖模块所需要的,但它们不在模块路径上(可能它们只在类路径上)。
其中一个模块(SparseBitSet)是automatic module(它没有module-info)。你没有直接依赖SparseBitSet,但是你的错误消息表明它是你的一个poi依赖所必需的。
类似地,您所依赖的公共数学库也是自动模块。
我对Gradle的经验有限,但我的经验是Gradle默认将自动模块放置在类路径上,而不是模块路径上(您可以通过设置覆盖这一点,但除此之外,据我所知,这就是它的工作方式)。
依靠自动模块的模块化项目的工作是不可取的海事组织,因此非模块化的建议。
使项目非模块化是否有任何缺点?
是的
然而,在这种情况下,我认为利大于弊。利益将是很少的,和不利的将是痛苦的。
最初没有被设计为模块化的可扩展性通常可以在模块化环境中工作,但不一定。很多事情都可能出错,包括split package issues。
在我看来,在类路径上运行不是模块化的软件比运行模块更可靠。一旦你对某些模块这样做,你就失去了很多使用模块的好处。
举例来说:
jlink
自动模块。jlink
只能链接带有module-info的模块。当你开始使用自动模块时,你必须忍受使用模块系统的痛苦(例如,必须处理您在问题中遇到的模块可访问性问题),同时获得很少的好处。
有些软件只被设计成一个模块。这包括最新JDK发行版的基本JDK系统中的所有模块以及JavaFX模块。在模块路径上获取JDK模块非常简单,因为这是自动发生的。在模块路径上获取JavaFX模块更加复杂(该过程在www.example.com上有文档openjfx.io)。
即使您的应用程序可能不是模块化的,它仍然可以使用模块化软件作为模块,以它们预期的方式使用(您不会失去使用模块化软件的能力)。
如果你打算写一个被其他人使用的库,并且你希望他们能够将其作为一个模块使用(例如,为了对库用户隐藏私有API),那么你应该使你的代码模块化(包括一个module-info.java)。但是如果你正在编写一个用于部署的应用程序,这不是一个问题。
Java软件的生态系统非常庞大。不幸的是,许多重要的库和框架都没有完全模块化(没有module-info.java为所有jar定义www.example.com)。这包括像Spring 6这样有影响力的大型框架。即使是most recent beta release of math commons 4也不包括模块-info.java。当你依赖非模块化软件(IMO)时,通常最好编写非模块化应用程序。