带有依赖注入的Java模块化

我们假定基于 OpenJDK 11 + OpenJFX 11 的应用程序。该代码库是在单个Java模块中组织的(请参阅A Guide to Java 9 Modularity作为参考)。

直到现在,我将所有基于 JavaFX 的项目与Google的依赖项注入框架 Guice 结合在一起。对于模块化项目,这似乎不起作用...

SQLiteCompassApplication.java

public class SQLiteCompassApplication extends Application {

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

    public void start(Stage stage) throws Exception {

         Injector injector = Guice.createInjector(new MyModule());

         FXMLLoader fxmlLoader = injector.getInstance(FXMLLoader.class);

         try(InputStream fxmlStream = getclass().getResourceAsStream("/view/View.fxml")) {

            Parent root = fxmlLoader.load(fxmlStream);
            stage.setScene(new Scene(root));
            stage.setTitle("SQLite Compass");
            stage.setOnCloseRequest(event -> system.exit(0));
            stage.show();
        }
    }
}

module-info.java

module org.x1c1b.sqlitecompass {

    requires javafx.controls;
    requires javafx.fxml;
    requires com.google.guice;

    exports org.x1c1b.sqlitecompass;
}

为了简化 Guice 配置,这意味着声明的 Guice 模块(与Java模块混淆的 not )不是粘贴但仍可用于非模块化项目。

执行此代码时,我收到以下异常:

Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field com.google.inject.Injector org.x1c1b.sqlitecompass.config.provider.FXMLLoaderProvider.injector accessible: module org.x1c1b.sqlitecompass does not "opens org.x1c1b.sqlitecompass.config.provider" to module com.google.guice
    at java.base/java.lang.reflect.accessibleObject.checkCanSetaccessible(accessibleObject.java:340)
    at java.base/java.lang.reflect.accessibleObject.checkCanSetaccessible(accessibleObject.java:280)
    at java.base/java.lang.reflect.Field.checkCanSetaccessible(Field.java:176)
    at java.base/java.lang.reflect.Field.setaccessible(Field.java:170)
    at com.google.guice@4.2.2/com.google.inject.internal.SingleFieldInjector.<init>(SingleFieldInjector.java:38)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore.getInjectors(MembersInjectorStore.java:126)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore.createWithListeners(MembersInjectorStore.java:93)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore.access$000(MembersInjectorStore.java:36)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:45)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:41)
    at com.google.guice@4.2.2/com.google.inject.internal.FailableCache$1.load(FailableCache.java:40)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3444)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2193)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2152)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2042)
    ... 39 more
Exception running application org.x1c1b.sqlitecompass.SQLiteCompassApplication

我可以通过将opens org.x1c1b.sqlitecompass.config.provider;粘贴到module-info.java来解决此问题。但这会导致进一步的例外...

我应该如何配置我的模块/ module-info.java,使其通常与 Google Guice 一起使用?可以结合使用 Google Guice Modularity 吗?

编辑

当我更改以下几行时,它似乎可以工作:

  • 将{}声明了我的 Guice 模块的exports org.x1c1b.sqlitecompass.config添加到module-info.java
  • 使用附加的VM选项--add-opens java.base/java.lang=com.google.guice
  • 执行程序

但是我想这是找到here而不是官方解决方案的解决方法。

qq842663987 回答:带有依赖注入的Java模块化

您必须打开您的所有软件包,Guice会通过反射来访问它们。 最简单的方法是将整个模块声明为open,方法是将此单词放在modulemodule-info.java的前面。

本文链接:https://www.f2er.com/3151353.html

大家都在问