Sponge can't find/create file

Sponge Build:7.0.0(Sponge Vanilla)
Java Version:1.8.0_144

[spoiler “Minecraft Logs”]
[22:07:28 ERROR] [STDERR]: java.nio.file.NoSuchFileException: experienceforclaims\config.conf
[22:07:28 ERROR] [STDERR]: at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
[22:07:28 ERROR] [STDERR]: at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
[22:07:28 ERROR] [STDERR]: at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
[22:07:28 ERROR] [STDERR]: at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(Unknown Source)
[22:07:28 ERROR] [STDERR]: at java.nio.file.Files.newByteChannel(Unknown Source)
[22:07:28 ERROR] [STDERR]: at java.nio.file.Files.createFile(Unknown Source)
[22:07:28 ERROR] [STDERR]: at com.gmail.tererechsama.claims.MainClaims.initializeConfig(MainClaims.java:75)
[22:07:28 ERROR] [STDERR]: at com.gmail.tererechsama.claims.MainClaims.onGameInit(MainClaims.java:61)
[22:07:28 ERROR] [STDERR]: at org.spongepowered.common.event.listener.GameLoadCompleteEventListener_MainClaims_onGameInit3.handle(Unknown Source)
[22:07:28 ERROR] [STDERR]: at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:95)
[22:07:28 ERROR] [STDERR]: at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:403)
[22:07:28 ERROR] [STDERR]: at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:430)
[22:07:28 ERROR] [STDERR]: at org.spongepowered.common.SpongeImpl.postEvent(SpongeImpl.java:213)
[22:07:28 ERROR] [STDERR]: at org.spongepowered.common.SpongeImpl.postState(SpongeImpl.java:221)
[22:07:28 ERROR] [STDERR]: at org.spongepowered.server.SpongeVanilla.initialize(SpongeVanilla.java:153)
[22:07:28 ERROR] [STDERR]: at net.minecraft.server.dedicated.DedicatedServer.handler$onServerInitialize$zpn000(SourceFile:1243)
[22:07:28 ERROR] [STDERR]: at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(SourceFile:191)
[22:07:28 ERROR] [STDERR]: at net.minecraft.server.MinecraftServer.run(SourceFile:434)
[22:07:28 ERROR] [STDERR]: at java.lang.Thread.run(Unknown Source)
[/spoiler]

Plugin Source: https://paste.ofcode.org/34bfqv7crDAsN9TRR8n2Le

So i have my defaultConfig.conf in resouces/asset/experienceforclaims/defaultConfig.conf and my plugin won’t create copy in configDir, there is just empty directory called experienceforclaims.

I wrote a bit a day or two ago about how the AssetManager works, so I’m going to redirect the general idea to that post rather than reiterate it here.

And if you’d like to see my ramble about how it works internally, that one is here.

Relating to your specific issue, the logs point to Files#createFile() as the issue. There are a couple of reasons why this might fail, but the one that should stand out is IOException - if an I/O error occurs or the parent directory does not exist.

This is indeed the case - the parent directory does not exist because the file is pointing to /experienceforclaims/config.conf. This is because you did not create your Path correctly in line 72 (25 in the paste) as Path#getFileName only returns the last element of the path, not all of them. You should be using Path#resolve instead.

Couple other notes on issues I saw or general recommendations:

  • You don’t have to store the Optional<Asset> (just get it when you need it, which should be once anyways). I’d also store the loader as a HoconConfigurationLoader directly, but that’s a personal choice.
  • In line 72 (30 in the paste), you make a call to Asset#copyToFile which internally uses Files#copy. This will result in a FileAlreadyExistsException because it’s already been created - see the first post I linked for two possibilities on how to this instead.
  • Many of your exceptions are marked as TODO (which is fine), but note that they will also stack up quickly - if one fails, then the ones after it will fail and result in fields not be initialized, which then cause a NullPointerException. You should make sure that your exceptions are grouped so these subsequent methods are only being called if the config has been loaded successfully.
  • Instead of using System.out.print() (which should be println() anyways), you should use the Logger for your plugin.
  • Your loading message shouldn’t be determined by the config; it should be a standard message that provides meaningful information. The same holds true for any log message in your plugin - as nice as translations are, they should be standardized so you know exactly where they’re coming from. I’d expect few people to touch this anyways.

If you have any followup questions, feel free to let me know. Welcome to Sponge!

1 Like