Intellij 2021.3.2,JavaFX Maven 项目未正确解析依赖项

Intellij 2021.3.2, JavaFX Maven project not resolving dependencies correctly

我按照以下步骤将 library 添加到我的 JavaFX 项目中:

  1. 文件 --> 项目结构 --> 项目设置 --> 库 --> + --> Maven
  2. 插入 Maven 坐标并选中“下载到 projectPath/libs”
  3. 在pom.xml中添加了正确的依赖声明
  4. 在模块-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.

所以我无法构建或测试它。