I’ve been trying to update some plugins to the new 4.1 API, and things are breaking. Most of it is stuff I can handle, but I can’t for the life of me get my plugin configs to work.
Its an NPE pointing to line 176. There’s two objects that could be null here.
getNode()
In which case the call to
getNode().getNode("Main","use-mod")
would throw a NPE. Or
getNode().getNode("Main","use-mod")
is null, and the call to
getNode().getNode("Main","use-mod").getBoolean()
is throwing the NPE. My suggestion would be to quickly add a null check and log whether either is null or not. Something like
if (getNode() == null) {
log.warn("getNode() returned null!");
}
if (getNode().getNode('Main','use-mod') == null) {
log.warn("getNode().getNode('Main', 'use-mod') returned null!");
}
would help you find the source. Note I replaced the quotes with apostrophes. Also, if you want to use that same project I was working on in my thread as a reference, you can see the whole thing’s Github Repository. Two things to note if you do:
I am using Sponge API 5, not 4, for MC 1.10.2.
My code is filled with a ton of logging as I am trying to debug right now.
Getting child nodes from a parent nodes should never be null, they might be virtual but not null. My best guess what’s happening here is that it fails to load the file because of an IOException, but a default root node is never supplied instead.
This isn’t because the ConfigurationNode is null. It’s because there is no boolean at this node. Whether the node physically exists in the configuration file or not, it should not return null, but instead return empty. What you need to do is check if node is virtual or not
ConfigurationNode node = getNode().getNode("Main","use-mod");
if(!node.isVirtual()) {
if(node.getBoolean()) {
final OverWorldModifier overWorld = new OverWorldModifier(
getNode().getNode("OreVeins"));
Sponge.getRegistry().register(OverWorldModifier.class
, overWorld);
}
}
This defaults the boolean to false and not null, thereby preventing the error.
Unless a config value is absolutely necessary or is expected to be a complex value, you should always provide a default. It makes your config file loading safer, as well as not preventing functionality in your plugin.
If you want to be more forcing on your user’s config, you can also test for null and if it is, set to false:
Boolean b = node.getBoolean();
if(b == null) {
node.setBoolean(false);
b = false;
}
Hopefully this helps mitigate any future problems you have with configs.
EDIT:
On the topic of what a config node returns, it will always return null if the node is virtual. The Configurate API does not use Optional<?> for forcing null checks, meaning that you have to be cautious while using configurations in Sponge. What was firing the NPE originally was the if statement, as it requires the value to be true or false, not null. This is true for both API versions 4.1 and 5. (I have tried it on both).
Are you guys sure that it’s a null problem when getting the boolean? node.getBoolean() Automatically returns false if no appropriate value is found. Boxing it when using node.getBoolean() seems kind of pointless.
If you really do want the boxed boolean you probably want to do node.getValue(TypeToken.of(Boolean.class)) instead. Using that you can also differentiate between no value found, and a false value found.
After looking through your project I see your problem
[10:23:18] [Server thread/ERROR] [oreveins]: Could not find the default config file in the jar! Did you open the jar and delete it?
You have your config file stored in the wrong place. Assets are not suppoosed to be stored in Java packages. I’ll just copy this from the docs
By default, a plugin’s assets resides in a directory named assets/myplugin/ where myplugin is the plugin ID. In most cases this default directory should be used but if you need to change it, you may do so by setting the assets attribute in your @Plugin annotation or mcmod.info file
Odd, when I’ve tested it in implementation, I have received null values. Either way, nodes are also supposed to be non-null, so it’s more likely what was null.