如何将 MongoDB 依赖项添加到 Java

How to add MongoDB dependecy to Java

我是 Maven 和 Gradle 的新手,我正在尝试将 MongoDB 依赖项添加到我的 JavaFx 应用程序。问题是即使我添加了对 build.gradle/pom 的依赖并单击加载更改,IntelliJ 也找不到 class。我尝试了很多方法,例如使缓存无效、全部删除并重新创建项目,但它仍然无法正常工作。 谢谢。

关于向模块化项目添加依赖项的建议

一些(自以为是的)建议:

  1. 不要导入不使用的库:

    • 例如controlsfx/formsfx/validatorfx/ikonli/bootstrapfx/tilesfx.
  2. 如果你不知道Gradle或Maven,使用the idea new JavaFX project wizard时选择Maven。

    • 对于一个简单的项目,Maven 可能更容易学习和理解。
  3. 如果您的项目在添加第 3 方依赖项时是模块化的,例如 mongo,您还需要将 module-info.java 文件更新为 require 新模块。

    • 默认情况下,Idea new JavaFX 项目向导将创建一个 module-info.java 文件,使您的项目模块化。
  4. 要确定所需模块的模块名称,您可以检查库的 source repository 或二进制 jar 中是否有 module-info 并使用它。

  5. 如果没有 module-info,如本例,它将是一个 automatic module

  6. 如果它是一个自动模块,您可以从 jar 中的 Automatic-Module-Name 清单 header 中找到模块名称,如果已定义的话。

  7. 如果没有定义manifest header,你可以根据链接的自动模块文档中的步骤从jar名称中找到模块名称。

  8. 您可能需要在 module-info 中添加其他语句,例如 opensexports 子句。

    • 您会知道这一点,因为您在尝试使用依赖模块中的代码时会收到 运行时间错误。这些 运行 时间错误将通知您由于 Java 模块系统的限制而出现访问错误。

即使您执行了上述所有操作,某些库也可能无法作为 Java 平台模块工作,因为它们未被编码以工作。在这种情况下,您应该 运行 将库从类路径中移出。在这种情况下,最好使您的项目成为 non-modular(同时将 JavaFX 库作为模块保留在模块路径中)。为此,请删除 module-info.java 文件并使用 VM 参数以允许访问 JavaFX 模块。有关此类配置的更多信息,请研究 non-modular 项目 openjfx.io 的文档,特别是 non-modular with Maven 部分。但是,只有在您失败或将项目作为模块化项目工作太不方便时才这样做。

如果您不理解上述步骤中的信息,请学习以下两个教程:

  1. 您选择的构建系统。
  2. Java 模块系统。
  3. 如何调整您的项目以使用 Java 模块系统。
  4. 如何使用构建系统与 Java 模块系统一起工作。

如果这很困难(可能很困难),您可以联系 third-party 库的供应商并请求帮助使库作为 Java 平台模块工作。

专供MongoDB

我确实在 MongoDB java 客户端库中尝试了上述步骤。这样做之后,我得出的结论是,最好(目前)将 JavaFX 中的 MongoDB 与您的项目以 non-modular 模式(即没有 module-info.java在你的项目中定义)。

这是因为 MongoDB 4.5.1:

  1. MongoDB因为没有提供合适的module-info.

    只能作为自动模块使用
  2. MongoDB 客户端来自多个 jar,并将其包定义拆分到多个 jar。

    • 据我所知,跨多个 jar 的 split-package 定义是 Java 平台模块系统不允许的配置。
    • com.mongodbmongodb-driver.jarmongodb-driver-core.jar 中都定义了 类。

这是 mongodb+JavaFX

的 non-modular 设置

所有文件均由 Idea New JavaFX 项目向导生成,并进行了一些修改,如下所述(non-modified 文件未列出)。

我不使用 MongoDB 并且没有 MongoDB 服务器设置,所以我只是验证了以下配置编译并尝试连接到服务器(然后连接失败由于没有服务器 运行ning).

为了简化设置,在向导定义期间,我选择了 JDK:“liberica-18 BellSoft Liberica version 18”。这是 Liberica 的“完整 JDK”版本,在其基础 JDK 发行版中包含 JavaFX 模块,因此我不需要定义 command-line 开关来启用 JavaFX 在编译和 运行 时间(这是一个痛苦的 error-prone 过程)。

默认情况下,MongoDB java 客户端不附带日志记录实现。要从客户端获取日志,您需要包含日志记录实现依赖项。对于这个例子,我选择包括 slf4j-simple 作为日志记录实现,如果你愿意,你可以用另一个兼容的库替换它。

MongoDB 客户端访问代码是从MongoDB quick start tutorial,但它使用的是本地访问 URL 而不是集群服务 URL 而不是 Atlas cloud-hosted MongoDB 实例。

module-info.java

文件已删除。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>mongodb-javafx-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>mongo</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <javafx.version>18</javafx.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-sync</artifactId>
            <version>4.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.36</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.9.0</version>
                <configuration>
                    <source>18</source>
                    <target>18</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

HelloApplication.java

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.bson.Document;

import java.io.IOException;

import static com.mongodb.client.model.Filters.eq;
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();

        // Replace the uri string with your MongoDB deployment's connection string
        String uri = "mongodb://localhost:27017";
        try (MongoClient mongoClient = MongoClients.create(uri)) {
            MongoDatabase database = mongoClient.getDatabase("sample_mflix");
            MongoCollection<Document> collection = database.getCollection("movies");
            Document doc = collection.find(eq("title", "Back to the Future")).first();
            System.out.println(doc.toJson());
        }
    }

    public static void main(String[] args) {
        launch();
    }
}