Better understanding how to get nodes and values in config

I’ve been working on a plugin and I recently got through an issue with extracting a config from a jar and writing it to the file system. Now the issue is that my plugin should be loading things from it, but is instead about as active as a potato.

Sorry if this seems like a wall of text, but I want to cover my bases.


“Technical” information in case it happens to be useful:
OS: Win10
IDE: Eclipse Neon
JDK: 1.8 Update 65
Dependency Management: Maven
Sponge API version: 4.1.0
Sponge Implementation and Version: spongeforge-1.10.2-2002-5.0.0-BETA-1544 (this is the jar name)
Forge Version: forge-1.10.2-12.18.0.2007-1.10.0-universal (again the jar name)


First thing is first. The config file is on the file system already (had a fun time figuring out how to extract it, earlier).

My root node for my config is a field in my main class:

private ConfigurationNode rootNode;

and assigned in my listener for GameStartedServerEvent:

try {
    rootNode = configLoader.load();
} catch (IOException e) {
    e.printStackTrace();
}

and the configLoader there is also a field in my main class:

@Inject
@DefaultConfig(sharedRoot = true)
private ConfigurationLoader<CommentedConfigurationNode> configLoader;

In my config, I have the following node structure (there is more but for simplicity this is what we will look at, no need to go 8 nodes deep if the first 2 don’t work)

config {  
  settings {
    mode="group"
  }
}

Here’s where things get hairy. The lines:

String s = rootNode.getNode("settings", "mode").getString();
log.info(s);

yields this:

[Server thread/INFO] [groupbroadcaster]: null

I thought maybe my understanding of the root node was off and I needed to try including my config’s first node. But like before,

String s = rootNode.getNode("config", "settings", "mode").getString();
log.info(s);

also ends up as

[Server thread/INFO] [groupbroadcaster]: null

At this point, I am questioning what exactly

rootNode = configLoader.load();

is doing. Its assigning something; I can’t think that rootNode is null, because I would be getting NPEs from rootNode.getNode(String) if this were the case. One thing I did notice was that as per the documentation, my rootNode was a ConfigurationNode, whereas the type returned by configLoader.load() is CommentedConfigurationNode. I changed the type of rootNode to match, however there was no difference.

Since rootNode is not null, and the type seems to not be an (immediate) issue, I tried to print out any child nodes:

for (ConfigurationNode node : rootNode.getChildrenList()) {
    log.info(node.getString());
}

No additional console output was given; the for loop did not run even once, telling me that rootNode has no children. One last idea came to mind, let’s see what happens if I do this:

log.info(rootNode.toString());

And the result is:

[Server thread/INFO] [groupbroadcaster]: SimpleCommentedConfigurationNode{super=SimpleConfigurationNode{[email protected], attached=true, key=null, parent=null, [email protected]}comment=null}

I don’t know enough about the configuration system to make much sense out of this, but I do think that maybe key being null is a red flag. That almost makes it sound like I have my rootNode field in memory, but it doesn’t have a key in the config that it points to. Is this the problem at hand? Or is there another issue that I am not aware of?

Where is your config? @DefaultConfig(sharedRoot = true) will put the config in /path/to/server/config/your_plugin.conf.

If you want a config in your private directory in the plugins directory, use sharedRoot = false.

Config is in /server root/config/, alongside the Forge configs.

Can you try adding a value to your rootNode and then save it to disk? It seems to me like you’re loading a different file than you think.

Is the config file named correctly?

for reference, “config”, “settings”, “mode” is correct. the root node is the unnamed node that describes the entire file, whereas config is just one child node.

Perhaps instead of posting code snippets, an entire class could be helpful because every bit of information counts.

> eclipse

triggered

People are allowed to have their preferences, Could you just once not try to push IntelliJ down someones throat who is happily using Eclipse?

If they were complaining about Eclipse, or asking which IDE people recommend then it might be appropriate, but making snide comments really isn’t constructive…

2 Likes

@bdubz4552 Could you post your complete code example? I’ll try running it locally and see if I can work out what’s happening for you.

You two just helped me a ton. I thought there was no naming convention for config files, but sure enough, the docs say:

If you set sharedRoot to true, then the returned pathname will be in a shared configuration directory. In that case, the configuration file for your plugin will be your_plugin_id.conf

When I saved the rootNode, despite some IOException about nodes and maps (not sure that’s relevant right now), I noticed a zero byte file with my plugin id. Checked the docs, and when using shared root, there is a naming convention. So the issue was that I had a different name on the config I was writing to disk. Grade A user error.

I am now able to pick up the mode node I was mentioning, which means I’m reading the right file. My remaining issue is navigating the rest of config, but from here I should be able to work my way through that.

Why yes I can. In case you still care, have a Github repo. https://github.com/RedPanda4552/GroupBroadcaster