java - 错误: [Dagger/MissingBinding] error message doesn't make sense

标签 java kotlin dagger-2 dagger

我得到:

C:\Users\Gieted\Projekty\CraftIt\runtime\build\tmp\kapt3\stubs\main\org\craftit\runtime\MainComponent.java:8: error: [Dagger/MissingBinding] java.lang.ClassLoader cannot be provided without an @Provides-annotated method.
public abstract interface MainComponent {
                ^
  A binding with matching key exists in component: org.craftit.runtime.server.ServerComponent
      java.lang.ClassLoader is injected at
          org.craftit.runtime.resources.packets.converters.DisplayMessageConverter(�, classLoader, �)
      org.craftit.runtime.resources.packets.converters.DisplayMessageConverter is injected at
          org.craftit.runtime.resources.packets.converters.PacketConverter(�, displayMessageConverter)
      org.craftit.runtime.resources.packets.converters.PacketConverter is injected at
          org.craftit.runtime.Bridge(�, packetConverter, �)
      org.craftit.runtime.Bridge is injected at
          org.craftit.runtime.server.initializers.VanillaServerInitializer(bridge, �)
      org.craftit.runtime.server.initializers.VanillaServerInitializer is injected at
          org.craftit.runtime.server.ServerModule.nativeServerInitializer(to)
      org.craftit.runtime.server.initializers.NativeServerInitializer is requested at
          org.craftit.runtime.server.ServerComponent.nativeServerInitializer() [org.craftit.runtime.MainComponent ? org.craftit.runtime.server.ServerComponent]
  It is also requested at:
      org.craftit.runtime.resources.entities.player.ChatType(�, classLoader)
      org.craftit.runtime.resources.entities.player.NativeConnectorImpl(�, classLoader)
      org.craftit.runtime.resources.packets.converters.SendChatMessageConverter(�, classLoader)
      org.craftit.runtime.text.NativeColorFactory(�, classLoader)
      org.craftit.runtime.text.StringTextComponentFactory(�, classLoader, �)
      org.craftit.runtime.text.StyleFactory(�, classLoader, �)
  The following other entry points also depend on it:
      org.craftit.runtime.server.ServerComponent.entityRegistry() [org.craftit.runtime.MainComponent ? org.craftit.runtime.server.ServerComponent]

因此“A binding with matching key exists in component: org.craftit.runtime.server.ServerComponent ”表明请求的绑定(bind)位于 ServerComponent 中,但同时is requested at org.craftit.runtime.server.ServerComponent.nativeServerInitializer()告诉我们缺少的绑定(bind)来自 ServerComponent ,这没有任何意义。有人可以向我解释发生了什么事吗?我应该在哪里搜索错误?

@ServerScope
@Subcomponent(modules = [ServerModule::class])
interface ServerComponent {

    fun pluginLoader(): PluginLoader

    fun entityRegistry(): EntityRegistry

    fun nativeServerInitializer(): NativeServerInitializer

    fun commandRegistry(): CommandRegistry

    fun pluginRegistry(): PluginRegistry

    @Subcomponent.Factory
    interface Factory {
        fun create(@BindsInstance server: Server): ServerComponent
    }
}
@Singleton
@Component(modules = [MainModule::class])
interface MainComponent {

    @Named("new")
    fun server(): Server

    @Component.Factory
    interface Factory {
        fun create(@BindsInstance configuration: Configuration): MainComponent
    }
}
class VanillaServer @Inject constructor(
    serverComponentFactory: ServerComponent.Factory
) : Server {

    override val entities: EntityRegistry
    override val commands: CommandRegistry
    override val plugins: PluginRegistry

    private val pluginLoader: PluginLoader

    private val nativeServerInitializer: NativeServerInitializer

    init {
        val component = serverComponentFactory.create(this)
        pluginLoader = component.pluginLoader()
        entities = component.entityRegistry()
        nativeServerInitializer = component.nativeServerInitializer()
        commands = component.commandRegistry()
        plugins = component.pluginRegistry()
    }

    override fun start() {
        nativeServerInitializer.startServer()
        pluginLoader.loadPlugins()
        plugins.forEach { it.enable() }
    }
}
@Module
abstract class ServerModule {
    companion object {
        @Provides
        @ServerScope
        fun classLoader(configuration: Configuration): ClassLoader =
            URLClassLoader(arrayOf(configuration.serverFile.toURI().toURL()))
    }

    @Binds
    @ServerScope
    abstract fun entityRegistry(to: VanillaEntityRegistry): EntityRegistry

    @Binds
    @ServerScope
    abstract fun nativeServerInitializer(to: VanillaServerInitializer): NativeServerInitializer
}

最佳答案

真正的问题远在第一行的右侧:

MainComponent.java:8: error: [Dagger/MissingBinding] java.lang.ClassLoader cannot be provided without an @Provides-annotated method.

您可以看到它在 ServerModule 中提供,但您收到消息是因为本来可以从 MainComponent 访问的内容无法到达您在 ServerComponent 中提供的 ClassLoader。这是有道理的:可以在 ServerComponent 中访问 MainComponent 中的绑定(bind),但无法在 MainComponent 中访问 ServerComponent 中的绑定(bind),除非通过 ServerComponent 工厂创建的特定 ServerComponent 实例进行检索。

这也是您的解决方案有效的原因:

VanillaServerInitializer and Bridge are server scoped, PacketConverter and DisplayMessageConverter were unscoped. If I try adding @ServerScope to PacketConverter I'm getting: error: [Dagger/IncompatiblyScopedBindings] org.craftit.runtime.MainComponent scoped with @Singleton may not reference bindings with different scopes. This is weird, because PacketConverter is never created by MainComponent.

Setting either singleton or server scope on every binding fixed the issue. But why have it happened in the first place?

由于您已取消了 PacketConverter 和 DisplayMessageConverter 的范围,因此 Dagger 尝试在无法提供 ClassLoader 的 MainComponent 中实现它们。 (如果可能的话,我也希望 PacketConverter 在 ServerComponent 中实现,但是您所描述的内容与从 MainComponent 的绑定(bind)中传递地访问它更一致,可以通过 @Named("new") Server 或您省略的 MainModule 中的绑定(bind)。)

无论如何,只要您只尝试从 @ServerScoped 和无作用域类访问绑定(bind),而不是从 @Singleton 或 MainComponent 可访问的类访问绑定(bind),您就应该没事。

关于java - 错误: [Dagger/MissingBinding] error message doesn't make sense,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68186786/

相关文章:

java - 如何在 ActiveMQ Artemis 集群中启用 REST

java - 如何避免在具有许多实例变量的类中使用getter/setter方法

gradle - 如何修复未解析的引用 : Gson?

android - 使用 .groupBy 对日期列表进行分组,不适用于日期格式 "YYYY-mm-dd",给出奇怪的输出 [Kotlin]

android - Dagger2 中 @Binds 与 @Provides 注释的用例是什么

android - @Produces 之后@Injects?

java - Dagger 2 范围和子组件

java - 我想在窗口 2 关闭 JAVAFX 后立即在窗口 1 上创建一个事件(添加了更多详细信息)

java - 如何使用 spring data jpa 存储库以编程方式对用户进行身份验证?

android - 我的布局文件没有显示在 setContent(R.layout.xml 文件)..?