我得到:
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
andBridge
are server scoped,PacketConverter
andDisplayMessageConverter
were unscoped. If I try adding@ServerScope
toPacketConverter
I'm getting:error: [Dagger/IncompatiblyScopedBindings] org.craftit.runtime.MainComponent scoped with @Singleton may not reference bindings with different scopes
. This is weird, becausePacketConverter
is never created byMainComponent
.
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/