1

I'm trying to create a plugin where I'm storing some Minecraft items' data along with some properties.

This is my YAML file's content:

rates:
- 391:
    mul: 10000
    store: 5000
- 392:
    mul: 9000
    store: 5000

So it's basically a list of maps of maps(I think so at least). This is my JAVA code where I'm trying to access the key 'mul' of '391':

List<Map<?,?>> rates;
rates= getConfig().getMapList("rates");
for(Map<?,?> mp : rates){
    Map <?,?> test = (Map<?,?>) mp.get("" + item);
    player.sendMessage(test.toString());// HERE I get null pointer exception, and the following lines if this line wasn't there in the first place
    player.sendMessage("Mul is: " + test.get("mul"));
    player.sendMessage("Store is: " + test.get("store"));
}

As per suggested answer, here is my test code, where I still get NullPointerException:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Map;

import net.sourceforge.yamlbeans.YamlException;
import net.sourceforge.yamlbeans.YamlReader;

public class Test {

public static void main(String[] args) throws FileNotFoundException, YamlException{
    YamlReader reader = new YamlReader(new FileReader("config.yml"));
    Map map = (Map) reader.read();
    Map itemMap = (Map) map.get("391");
    System.out.println(itemMap.get("mul"));//This is where I get the exception now
    System.out.println(itemMap.get("store"));
}
}
Akash Agarwal
  • 2,326
  • 1
  • 27
  • 57
  • 2
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – pvg Dec 21 '16 at 16:50
  • 1
    @pvg I know what NullPointerException is, I just don't know why is it happening to my code. This has to do with yaml parsing I suppose. – Akash Agarwal Dec 21 '16 at 17:29
  • It's still a dupe because the answer is about how to diagnose the cause of an NPE - do that and you'll almost certainly sort out your problem. You've also not provided the specific exception you got nor is your code something that others can try - take a look at the suggestions on how to write a [MCVE] – pvg Dec 21 '16 at 17:46
  • @pvg About the NullPointerException, I've been trying to get this thing right since an hour and couldn't do it, which is why I posted here. I didn't disagree that this isn't a duplicate, but I also didn't agree that it is. I am looking for a specific solution for a more specific problem. The MVC part, sorry about that. I had high expectations of finding a bukkit programmer here and I just focussed on minimising the code more(which is wrong, I accept). – Akash Agarwal Dec 21 '16 at 17:59
  • It doesn't really matter how long you've spent on it, what matters is what the problem is, whether or not it's been answered before and how it could also help others. You still haven't included the actual exception stack trace. – pvg Dec 21 '16 at 18:50
  • Your test code ignores the toplevel key 'rates' so of course it NPEs. This would have been obvious if you'd followed the suggestions on diagnosing an NPE in the answer already provided. Please read it again and apply what's there to your actual code. – pvg Dec 21 '16 at 19:01

2 Answers2

3

Parsing yaml by hand can be tedious and error prone. It might be easier to use a library like yamlbeans.

http://yamlbeans.sourceforge.net/

package com.jbirdvegas.q41267676;

import com.esotericsoftware.yamlbeans.YamlReader;

import java.io.StringReader;
import java.util.List;
import java.util.Map;

public class YamlExample {
    public static void main(String[] args) throws Exception {

        String yamlInput =
                "rates:\n" +
                        "- 391:\n" +
                        "    mul: 10000\n" +
                        "    store: 5000\n" +
                        "- 392:\n" +
                        "    mul: 9000\n" +
                        "    store: 5000";

        YamlReader reader = new YamlReader(new StringReader(yamlInput));
        Map map = (Map) reader.read();
        // rates is a list
        List<Map> rates = (List<Map>) map.get("rates");
        // each item in the list is a map
        for (Map itemMap : rates) {
            // each map contains a single map the key is [ 391|392 ]
            itemMap.forEach((key, value) -> {
                System.out.println("Key: " + key);
                // the value in in this map is itself a map
                Map embededMap = (Map) value;
                // this map contains the values you want
                System.out.println(embededMap.get("mul"));
                System.out.println(embededMap.get("store"));
            });
        }
    }
}

This prints:

Key: 391
10000
5000
Key: 392
9000
5000

This is a simple usecase but yamlbeans also provides GSON like reflective class model population if that would be better suited for your needs.

JBirdVegas
  • 10,855
  • 2
  • 44
  • 50
1

Your assumptions that that YAML is a list of maps is wrong. At the top level is is a map with a single key-value pair, the key of which is rates and the value is a sequence with two elements.

Each of those elements is mapping with a single key value pair, the key of which is a number (391, 392) and the value of which is a mapping with two key-value pairs each.

That there is a dash (-) at the left hand doesn't imply the that at the top level there is a sequence (there are no lists in a YAML file, that is construct in your programming language). If a sequence is a value for a specific key, those sequence elements can be at the same indentation level as the key, as in your YAML file.

Anthon
  • 69,918
  • 32
  • 186
  • 246