0

I am having trouble with my code. This is my first time using a Map and for some reason the Gate that is added in the 2nd try block is null. I cannot spot the error. The error first shows itself in the last try block where i get nullpointer when i try to set the inputgates.

The file that is given the to the function has several lines where each line looks like this: starts with a name for the gate, then the type for the gate, then a number of inputgates. (Gates previouse created). There is a type of gate called signalgate that just acts as a startgate. Has no input, just an output. We are talking about NAND, AND, OR gates and such.

Thanks in advance!

public static String Capital(String s){
    String string = s.substring(0,1).toUpperCase() + s.substring(1).toLowerCase();
    string = string + "Gate";
    return string;
}

public static Map<String, Gate> createGates(File file){
    //variabler.
    BufferedReader bufferedReader = null;
    String[] lines = null;
    String line;
    Map<String, Gate> map = new LinkedHashMap<String, Gate>();
    int index = 0;
    Gate g;

    try{
        //tests reading the file
        bufferedReader = new BufferedReader(new FileReader(file));
        //As long as there still are lines left
        while((line = bufferedReader.readLine()) != null){
            index++;
            //as long as the line's not a comment.
            if(line.trim().charAt(0) == '*' || line.trim().charAt(0) == '/'){
                continue;
            }else{
                lines = line.split("\\s+");
            }
            //Gör namnet till att börja med stor bokstav och resten blir små bokstäver.
            lines[1] = Capital(lines[1]);
            try{
                System.out.println("hej");
                //Skapar en instans av en gate med class.metoden
                g = (Gate) Class.forName(lines[1]).newInstance();
                //sätter namnet. Detta använder vi senare
                g.setName(lines[0]);
                //För in dom i mapen.
                map.put(g.getName(), g);

            }catch (InstantiationException e) {
                new GateException("Something went wrong instantiating the gate " + lines[0] + " on line " + index + " in the code");
            } catch (IllegalAccessException e) {
                new GateException("Something went wrong in the CreateGates-function for gate " + lines[0] + " on line " + index + " in the code");
            } catch (ClassNotFoundException e) {
                new GateException("The gate " + lines[0] + " written in the file does not exist. This error occured on line " + index);
            }
        }
    }catch (FileNotFoundException e){
        new GateException("Could not load the given file.");
    } catch (IOException e) {
        new GateException("Something went wrong while trying to read the file. (NOT filenotfoundexception)");
    } 


    //läser filen på nytt som det står i labbbeskrivningen
    try{
        //samma som ovan. Reader, string och array med strings.
        BufferedReader br = new BufferedReader(new FileReader(file));
        String l = null;
        String[] li = null;

        while((l = br.readLine()) != null){

            //as long as the line's not a comment.
            if(l.trim().charAt(0) == '*' || l.trim().charAt(0) == '/'){
                //Omd et är en kommentar, hoppa och kör loopen nästa gång direkt.
                continue;
            }else{
                //annars splitta den
                li = l.split("\\s+");
            }

            //om det är en deklarering av en signalgate så¨ska den forstätta, annars ska den sätta inputs osv som den ska.
            if(li.length == 2){
                continue;
            }else{
                Gate gate = map.get(li[0]);
                for(int i = 2; i < li.length; i++){
                    System.out.println(map.get("b"));
                    gate.setInputGate(map.get(li[i]));
                }
            }

        }
    }catch (FileNotFoundException e){
        throw new GateException("Error loading the file");
    }catch (IOException e){
        throw new GateException("Error reading the file");
    }

    return map;
}
DakkVader
  • 142
  • 1
  • 8
  • Please post a full stack trace for the error you are seeing. –  Dec 21 '13 at 13:17
  • I'm thinking we'll need `Gate.java`. Instead of reading from a file, could you add in three or four lines from the file that should be creating the `Gate`s? – Teepeemm Dec 21 '13 at 13:17
  • http://lpaste.net/97334 There is the errormessage and further down is how the file looks. Lines that start with * or / are comments. there are no errors in gateprog.java. That is the file that was given to us. We are not to alter it. – DakkVader Dec 21 '13 at 16:15
  • http://lpaste.net/97335 And here is the Gate.java – DakkVader Dec 21 '13 at 16:18
  • just a side note, you might find it easier to use apache's IOUtils to read in the entire file to a string, and then use the string's split method with new line as a regex. That will give you an array of all the lines, and significantly reduce the number of lines of code you have. The only problem is it would load the entire file into memory, so it would not be an option for large files. I also agree with Nick's advice about code re-use. You could re-write your create-gates method to take a call-back object to handle the lines. Then implement the call back with an anonymous inner class. – msknapp Dec 21 '13 at 18:33

1 Answers1

0

TL;DR: I'd venture your problem is on lines 90, 92 and 94: you're not calling throw on these newly created exceptions.

The classes are probably never getting instantiated due to some class problem or another (fixing the above will show you), so this is caught but as mentioned will not interrupt the execution or log (probably), but will not actually add to the map. It could, of course, be something else...

As an aside, some code quality points:

  • Re-use code wisely: most of that file-reading block could be extracted to a method which would make debugging (or reading) things like this much easier.
  • the Capital(String s) method should usually have small 'c' (or consider the useful WordUtils.capitalizeFully)
  • Always check values coming back from map.get(foo) for null.
declension
  • 4,110
  • 22
  • 25
  • I added throws, and now i get the error at line 94, that the gate does not exists. Obviously because the gate created is null. Does anyone have an idea as to why it does not cerate the gate properly? – DakkVader Dec 21 '13 at 18:58
  • Doing some research on classnotfound. Will get back with what i come up with – DakkVader Dec 21 '13 at 19:00
  • I can't really understand why it gives me that exception :/ I DO have a class called SignalGate.java in the same folder as Gate, and the other classes can inherit correctly etc. – DakkVader Dec 21 '13 at 19:29
  • Good, so it was that. Are they in the same package, and on the [classpath](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html)? Messing with dynamic instantiation is always a bit nasty in Java. What people normally do here is create a [Factory](http://en.wikipedia.org/wiki/Factory_method_pattern) class; here you'd make, say, a `create(class extends Gate> type)` method responsible for making any Gate dynamically. You can also avoid `newInstance()`, if you want, by using a `switch` on the `type` parameter... The point is really that you can test that logic separately. – declension Dec 21 '13 at 22:57
  • They are in the same classpath and in the same folder, so it shouldnät be a problem right? Will look up ways to dynamically create classes – DakkVader Dec 22 '13 at 10:47
  • In the documents i can find "ClassNotFoundException - if the class cannot be located" when using the forname, so i'm guessing it is as simple as that. Wonder how the classpath got messed up. All the other classes can inherit properly etc etc :/ – DakkVader Dec 22 '13 at 10:59
  • Have you debugged / logged the _exact_ class name string before trying to instantiate it? Capitals and spaces matter... – declension Dec 22 '13 at 11:02
  • Yes, the classname is the exact one :( – DakkVader Dec 22 '13 at 12:51
  • Well, something is wrong clearly. Take out `forName(name).newInstance()` and do it with `if name.equals("Blah")` etc (or `switch` directly on the String in Java 7) and use `g = new BlahGate()` etc, until you find the problem. The compiler will help you, avoiding any runtime classpath issues from the current dynamic way. – declension Dec 22 '13 at 13:30
  • Aparently we are not allowed to use switchstatement in the assignment so i'll have to go with forname :/ Still stuck with the same error... ! gah! – DakkVader Dec 23 '13 at 14:45