Intellij 2021.3.2,JavaFX Maven 项目未正确解析依赖项
Intellij 2021.3.2, JavaFX Maven project not resolving dependencies correctly
我按照以下步骤将 library 添加到我的 JavaFX 项目中:
- 文件 --> 项目结构 --> 项目设置 --> 库 --> + --> Maven
- 插入 Maven 坐标并选中“下载到 projectPath/libs”
- 在pom.xml中添加了正确的依赖声明
- 在模块-info.java 中添加了 'requires module'
将库导入我的 class 似乎可行,但从库中调用方法后,结果是
Caused by: java.lang.ClassNotFoundException: org.web3j.utils.Numeric
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
现在,我最初认为是库问题,但在普通 Maven 项目中重现了 相同的步骤 (并尝试 运行 完全相同的代码片段)完美运行。
知道为什么会发生这种情况吗?我在导入库时做错了什么吗?
HELLOAPPLICATION.JAVA
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load() , 320 , 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
Web3j web3j = Web3j.build(new HttpService("http://127.0.0.1:8545"));
web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(new BigInteger("14000000")), true);
}
public static void main(String[] args) {
launch();
}
}
编辑:
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demo</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.8.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>web3j-evm</artifactId>
<version>4.9.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.demo/com.example.demo.HelloApplication</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
模块-INFO.JAVA
module com.example.demo {
requires javafx.controls;
requires javafx.fxml;
requires core;
opens com.example.demo to javafx.fxml;
exports com.example.demo;}
从评论来看,您似乎使用了一些不太常用的库。有时,这些类型的库不会更新为与 Java Platform Module System 兼容。除非您另有所知,否则我认为假设可能是安全的。
定义一个 non-modular 项目
处理此类依赖关系的最简单方法是使您的项目non-modular:删除module-info.java
.
但 JavaFX 本身仅作为模块受支持。因此,即使您的项目及其依赖项 non-modular,您仍应将 JavaFX 库放在模块路径中。
使用包含 JavaFX
的 JDK
要完成这样的设置(non-modular 使用 JavaFX 模块的应用程序),最简单的方法是依赖 JDK 或包含 JavaFX 模块的 JRE,例如 Zulu JDK FX distribution or the Liberica Full JDK 分配。 使用正确的发行版很重要,因为 Zulu 和 Liberica 的基础 JDK 发行版不包括 JavaFX。
使用不包含 JavaFX 的基础 JDK
再做一些工作,您就可以使用 OpenJDK。您可以通过从 maven repository with a build tool, or a manual download of the modules and SDK from Gluon 获取 JavaFX 模块来做到这一点。在所有构建和执行步骤中,您需要确保所有这些模块都在模块路径上并通过 VM 参数或 module-info.java
.
声明到模块系统
使用 Maven 构建
对于 Maven 构建,您需要将每个模块单独添加到模块路径,因为它们都位于本地 .m2
存储库(现代 Maven 系统和一些 IDE,例如 Idea,将自动执行此操作,其他 IDE(例如 VSCode 可能不会)。
使用 SDK 构建
或者,不要通过 Maven 添加对 JavaFX 模块的依赖。相反,下载 JavaFX SDK 并通过 VM 参数 --module-path
和 --add-modules
添加 JavaFX 模块。 getting started documentation at openjfx.io.
中记录了将 JavaFX 模块添加到 OpenJDK 的过程
关于 openjfx.io Maven 原型的注释
请注意,围绕此的 openjfx.io 入门文档提到了 Maven 原型。我的建议是不要使用它们,因为如果您尝试从 IDE 中使用它们,它们真的很难使用。相反,使用想法 new JavaFX project wizard,要么保留它为模块化项目生成的 module-info.java,要么删除它并为 non-modular 项目手动指定 JavaFX 模块 VM 参数。
您的项目构建有问题
就你的实际项目而言,我遇到了duffymo在评论中指出的相同错误:
I can't resolve all the dependencies for web3jm-evm from Maven Central. It's pulling in a bunch of JARs from org.hyperledger.besu that aren't in Maven Central.
所以我无法构建或测试它。
我按照以下步骤将 library 添加到我的 JavaFX 项目中:
- 文件 --> 项目结构 --> 项目设置 --> 库 --> + --> Maven
- 插入 Maven 坐标并选中“下载到 projectPath/libs”
- 在pom.xml中添加了正确的依赖声明
- 在模块-info.java 中添加了 'requires module'
将库导入我的 class 似乎可行,但从库中调用方法后,结果是
Caused by: java.lang.ClassNotFoundException: org.web3j.utils.Numeric
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
现在,我最初认为是库问题,但在普通 Maven 项目中重现了 相同的步骤 (并尝试 运行 完全相同的代码片段)完美运行。
知道为什么会发生这种情况吗?我在导入库时做错了什么吗?
HELLOAPPLICATION.JAVA
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load() , 320 , 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
Web3j web3j = Web3j.build(new HttpService("http://127.0.0.1:8545"));
web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(new BigInteger("14000000")), true);
}
public static void main(String[] args) {
launch();
}
}
编辑:
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demo</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.8.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>web3j-evm</artifactId>
<version>4.9.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.demo/com.example.demo.HelloApplication</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
模块-INFO.JAVA
module com.example.demo {
requires javafx.controls;
requires javafx.fxml;
requires core;
opens com.example.demo to javafx.fxml;
exports com.example.demo;}
从评论来看,您似乎使用了一些不太常用的库。有时,这些类型的库不会更新为与 Java Platform Module System 兼容。除非您另有所知,否则我认为假设可能是安全的。
定义一个 non-modular 项目
处理此类依赖关系的最简单方法是使您的项目non-modular:删除module-info.java
.
但 JavaFX 本身仅作为模块受支持。因此,即使您的项目及其依赖项 non-modular,您仍应将 JavaFX 库放在模块路径中。
使用包含 JavaFX
的 JDK要完成这样的设置(non-modular 使用 JavaFX 模块的应用程序),最简单的方法是依赖 JDK 或包含 JavaFX 模块的 JRE,例如 Zulu JDK FX distribution or the Liberica Full JDK 分配。 使用正确的发行版很重要,因为 Zulu 和 Liberica 的基础 JDK 发行版不包括 JavaFX。
使用不包含 JavaFX 的基础 JDK
再做一些工作,您就可以使用 OpenJDK。您可以通过从 maven repository with a build tool, or a manual download of the modules and SDK from Gluon 获取 JavaFX 模块来做到这一点。在所有构建和执行步骤中,您需要确保所有这些模块都在模块路径上并通过 VM 参数或 module-info.java
.
使用 Maven 构建
对于 Maven 构建,您需要将每个模块单独添加到模块路径,因为它们都位于本地 .m2
存储库(现代 Maven 系统和一些 IDE,例如 Idea,将自动执行此操作,其他 IDE(例如 VSCode 可能不会)。
使用 SDK 构建
或者,不要通过 Maven 添加对 JavaFX 模块的依赖。相反,下载 JavaFX SDK 并通过 VM 参数 --module-path
和 --add-modules
添加 JavaFX 模块。 getting started documentation at openjfx.io.
关于 openjfx.io Maven 原型的注释
请注意,围绕此的 openjfx.io 入门文档提到了 Maven 原型。我的建议是不要使用它们,因为如果您尝试从 IDE 中使用它们,它们真的很难使用。相反,使用想法 new JavaFX project wizard,要么保留它为模块化项目生成的 module-info.java,要么删除它并为 non-modular 项目手动指定 JavaFX 模块 VM 参数。
您的项目构建有问题
就你的实际项目而言,我遇到了duffymo在评论中指出的相同错误:
I can't resolve all the dependencies for web3jm-evm from Maven Central. It's pulling in a bunch of JARs from org.hyperledger.besu that aren't in Maven Central.
所以我无法构建或测试它。