【问题标题】:error: [Dagger/MissingBinding] error message doesn't make sense错误:[Dagger/MissingBinding] 错误消息没有意义
【发布时间】:2021-06-29 23:34:13
【问题描述】:

我明白了:

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”表示请求的绑定在ServerComponent 中找到,但同时is requested at org.craftit.runtime.server.ServerComponent.nativeServerInitializer() 表示缺少的绑定来自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
}

【问题讨论】:

  • DisplayMessageConverterPacketConverterBridgeVanillaServerInitializer 是无作用域还是 @ServerScope
  • @Nitrodon VanillaServerInitializerBridge 是服务器范围的,PacketConverterDisplayMessageConverter 是无范围的。如果我尝试将@ServerScope 添加到PacketConverter 我得到:error: [Dagger/IncompatiblyScopedBindings] org.craftit.runtime.MainComponent scoped with @Singleton may not reference bindings with different scopes。这很奇怪,因为PacketConverter 从未由MainComponent 创建。
  • 在每个绑定上设置单例或服务器范围解决了这个问题。但为什么会发生呢?

标签: java kotlin dagger-2 dagger


【解决方案1】:

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

MainComponent.java:8: 错误:[Dagger/MissingBinding] java.lang.ClassLoader 不能在没有 @Provides-annotated 方法的情况下提供。

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

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

VanillaServerInitializerBridge 是服务器范围的,PacketConverterDisplayMessageConverter 是无范围的。如果我尝试将@ServerScope 添加到PacketConverter 我得到:error: [Dagger/IncompatiblyScopedBindings] org.craftit.runtime.MainComponent scoped with @Singleton may not reference bindings with different scopes。这很奇怪,因为PacketConverter 从未由MainComponent 创建。

在每个绑定上设置单例或服务器范围解决了这个问题。但为什么会发生这种情况呢?

由于您已将 PacketConverter 和 DisplayMessageConverter 设置为无作用域,因此 Dagger 尝试在无法提供 ClassLoader 的 MainComponent 中实现它们。 (如果可能的话,我也希望 PacketConverter 能够在 ServerComponent 中实现,但是你所描述的将更符合从 MainComponent 的绑定传递的某个地方访问它,或者通过 @Named("new") Server 或 MainModule 中的绑定你'已经省略了。)

在任何情况下,只要您只尝试从 @ServerScoped 和无作用域的类访问绑定,而不是从 @Singleton 或 MainComponent 可访问的类,您应该没问题。

【讨论】:

  • 让我大开眼界:“既然你已经没有了 PacketConverter 和 DisplayMessageConverter 的作用域,Dagger 试图在你的 MainComponent 中实现它们”。我认为文档中没有提到这一点,但这非常重要。谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 2022-01-17
  • 2021-12-13
  • 1970-01-01
相关资源
最近更新 更多