Java 模块找不到包

问题描述 投票:0回答:2

我使用 Retrofit 2 作为我制作的 API,并使用 Retrofit Gson 将 API 响应转换为对象。我有一个包含 JSON 模型的包(作为一个类),我需要 Gson 来访问这些模型。

当我添加行来打开 Gson 包时,我在建筑物上收到一条错误消息,指出他们无法访问该包。我尝试打开上面的包(我知道它可以工作,因为

javafx.fxml
使用它),但后来我收到此错误(不是在建筑物上,而是当我在运行时使用 Gson 时)

Exception in thread "DefaultDispatcher-worker-2" java.lang.IllegalArgumentException: Unable to create converter for class fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get.LoginResponse
    for method BankApi.login
    at [email protected]/retrofit2.Utils.methodError(Utils.java:56)
    at [email protected]/retrofit2.HttpServiceMethod.createResponseConverter(HttpServiceMethod.java:139)
    at [email protected]/retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:97)
    at [email protected]/retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
    at [email protected]/retrofit2.Retrofit.loadServiceMethod(Retrofit.java:235)
    at [email protected]/retrofit2.Retrofit$1.invoke(Retrofit.java:177)
    at jdk.proxy2/com.sun.proxy.jdk.proxy2.$Proxy6.login(Unknown Source)
    at [email protected]/fr.plaglefleau.banksystemdesktop.SignInController$signIn$1.invokeSuspend(SignInController.kt:95)
    at kotlin.stdlib/kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.core/kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
    at kotlinx.coroutines.core/kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:589)
    at kotlinx.coroutines.core/kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:806)
    at kotlinx.coroutines.core/kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:710)
    at kotlinx.coroutines.core/kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:697)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@5216989, Dispatchers.Default]
Caused by: com.google.gson.JsonIOException: Failed making field 'fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get.LoginResponse#message' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
    at [email protected]/com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38)
    at [email protected]/com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286)
    at [email protected]/com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
Caused by: com.google.gson.JsonIOException: Failed making field 'fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get.LoginResponse#message' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.

    at [email protected]/com.google.gson.Gson.getAdapter(Gson.java:556)
    at [email protected]/retrofit2.converter.gson.GsonConverterFactory.responseBodyConverter(GsonConverterFactory.java:64)
    at [email protected]/retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:418)
    at [email protected]/retrofit2.Retrofit.responseBodyConverter(Retrofit.java:401)
    at [email protected]/retrofit2.HttpServiceMethod.createResponseConverter(HttpServiceMethod.java:137)
    ... 12 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.String fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get.LoginResponse.message accessible: module fr.plaglefleau.banksystemdesktop does not "opens fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get" to module com.google.gson
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.String fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get.LoginResponse.message accessible: module fr.plaglefleau.banksystemdesktop does not "opens fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get" to module com.google.gson

    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
    at [email protected]/com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:35)
    ... 19 more

这是我的模块-info.java

module fr.plaglefleau.banksystemdesktop {
    requires javafx.controls;
    requires javafx.fxml;
    requires kotlin.stdlib;
    requires TranslationLibrary.main;
    requires kotlinx.coroutines.core;
    requires org.jetbrains.annotations;
    requires retrofit2;
    requires retrofit2.converter.gson;
    requires com.google.gson;

    opens fr.plaglefleau.banksystemdesktop to javafx.fxml, retrofit2.converter.gson;
    exports fr.plaglefleau.banksystemdesktop;
}

我在GitHub上推送了项目,这是链接

java gson retrofit2
2个回答
0
投票

根异常中已经提供了解决方案(强调我的):

原因:java.lang.reflect.InaccessibleObjectException:无法 将字段设置为 private Final java.lang.String fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get.LoginResponse.message 可访问:模块 fr.plaglefleau.banksystemdesktop 无法“打开” fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get”到 模块 com.google.gson

换句话说,您需要修改您的

module-info.java
并添加以下
opens
语句。

opens fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get 
        to com.google.gson;

[..]我在上层包装上打开它

正如 Holger 的评论中已经提到的,虽然 Java 中包的命名是(或者,似乎是)分层的,但包不是;每个包名都定义了自己独立的命名空间。

换句话说,打开包装

fr.plaglefleau.banksystemdesktop
并不会同时打开包装
fr.plaglefleau.banksystemdesktop.api.models.bankapi.response.get
。就 Java 而言,它们是两个不同且独立的实体(即后者不嵌套在前者中)。


0
投票

关于更新后看到的

Package ... not found in module
错误
module-info.java

问题很可能是您的项目由 Java 和 Kotlin 代码组成,而您要打开的包是 Kotlin 代码的一部分。

您可以通过以下任一方法解决此问题:

  • 调整您的
    build.gradle
    以便
    compileJava
    任务可以看到 Kotlin 类,请参阅 Kotlin 文档
  • 将完整的模块开放给所有其他模块进行反射,而不是单独的包。也就是说,更改您的
    module-info.java
    并删除
    opens ... to ...;
    并改为写入
    open module
    open module fr.plaglefleau.banksystemdesktop {
        requires ...
    }
    
    另请参阅了解 Java 9 模块。然而,当 Gson 或其他库意外地使用了您实际上并不想要打开的某个包中的类的反射时,这可能会使故障排除变得更加困难。

请注意,Gson 主要是为 Java 设计的。它可能适用于某些 Kotlin 功能,但不适用于所有功能(例如,不考虑可空性)。由于您的模型类是用 Kotlin 编写的,因此最好使用具有明确 Kotlin 支持的 JSON 库,例如 https://github.com/square/moshi相应的 Retrofit 转换器

© www.soinside.com 2019 - 2024. All rights reserved.