Configuration directory path injection giving me a Null

So, I’m pretty sure this is a super obvious mistake but I’m absolutely out of ideas… Basically, I’m using the @Inject annotation to get a path to my plugin’s config directory and it’s giving me a null…

I’m injecting it like this: (Kotlin)

@Inject
@ConfigDir(sharedRoot = false)
private val configDir: Path? = null

According to the log (if I’m reading it correctly), the Injector cannot be created because of a KotlinNullPointerException, but that’s thrown AFTER the injection should happen (line 47)

Line 47 looks like this, the injection begins on line 43:

private val configFile: Path = if(configDir == null) throw KotlinNullPointerException() else Paths.get(configDir.toString() + "/config.conf")

When I remove the if and make the Path nullable, I still get the same error, just on a different line:

private val configLoader = HoconConfigurationLoader.builder().setPath(configFile!!).build()

So… Any ideas?

Sponge Build: 1.12.2-7.1.4
Java Version: 1.8.0_191

Log:

[23:39:30 ERROR] [Sponge]: Failed to load plugin: Konjiru 0.0.1 (from mods\konjiru-1.0-SNAPSHOT-jar-with-dependencies.jar)
com.google.inject.CreationException: Unable to create injector, see the following errors:

1) Error injecting constructor, kotlin.KotlinNullPointerException
  at org.districraft.konjiru.KonjiruMain.<init>(KonjiruMain.kt:30)
  at org.spongepowered.common.inject.plugin.PluginModule.configure(PluginModule.java:59)
  while locating org.districraft.konjiru.KonjiruMain

1 error
        at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:184) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InjectorImpl.createChildInjector(InjectorImpl.java:232) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InjectorImpl.createChildInjector(InjectorImpl.java:236) ~[sponge.jar:1.12.2-7.1.4]
        at org.spongepowered.server.plugin.VanillaPluginContainer.<init>(VanillaPluginContainer.java:43) ~[VanillaPluginContainer.class:1.12.2-7.1.4]
        at org.spongepowered.server.plugin.VanillaPluginManager.loadPlugin(VanillaPluginManager.java:166) ~[VanillaPluginManager.class:1.12.2-7.1.4]
        at java.util.ArrayList.forEach(Unknown Source) ~[?:1.8.0_191]
        at org.spongepowered.server.plugin.VanillaPluginManager.loadPlugins(VanillaPluginManager.java:89) ~[VanillaPluginManager.class:1.12.2-7.1.4]
        at org.spongepowered.server.SpongeVanilla.preInitialize(SpongeVanilla.java:120) ~[SpongeVanilla.class:1.12.2-7.1.4]
        at net.minecraft.server.dedicated.DedicatedServer.handler$onServerLoad$bba000(SourceFile:1234) ~[nz.class:?]
        at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(SourceFile:117) ~[nz.class:?]
        at net.minecraft.server.MinecraftServer.run(SourceFile:434) ~[MinecraftServer.class:?]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_191]
Caused by: kotlin.KotlinNullPointerException
        at org.districraft.konjiru.KonjiruMain.<init>(KonjiruMain.kt:47) ~[KonjiruMain.class:?]
        at org.districraft.konjiru.KonjiruMain$$FastClassByGuice$$877b3dce.newInstance(<generated>) ~[KonjiruMain.class:?]
        at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:111) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:90) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:268) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:194) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:205) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:199) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1085) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:199) ~[sponge.jar:1.12.2-7.1.4]
        at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:180) ~[sponge.jar:1.12.2-7.1.4]
        ... 12 more

Because it is val and not var, it cannot reassign the variable after the object has been constructed. You have three options: constructor parameter val, nullable var, or nonnullable lateinit var. I would recommend the first one - injected fields are only really useful in Java where assigning from a constructor is boilerplate, unlike Kotlin where the constructor is in the class header and fields can be auto-assigned from constructor parameters.

1 Like

Oooooooh. I knew it would be something simple like this :smiley: Thanks mate.