Java: "The JAR file has no attachment" error, but only when I override the toString() method

StackOverflow https://stackoverflow.com/questions/20902212

  •  23-09-2022
  •  | 
  •  

Question

I have written a class, called Node, which represents nodes in a graph. It looks like this:

public class Node{
    protected ArrayList<Node> neighbours = new ArrayList<>();

    public Node(ArrayList<Node> neighbours){
        for(int i=0;i<neighbours.size();i++){
            this.neighbours.add(neighbours.get(i));
        }
    }
    public Node(){}
    public void setNeighbours(ArrayList<Node> neighbours){
        this.neighbours.clear();
        this.neighbours.addAll(neighbours);
    }
    public ArrayList<Node> getNeighbours(){
        return this.neighbours;
    }
    @Override
    public String toString(){
        String s = new String(""+this.neighbours);  
        return s;   
    }
}

I tested it before overriding the toString method, creating a basic graph. The output was correct, the only problem was that the output was the address of each object, instead of the object itself( like Node@61672c01 for example). After writing thetoString method, I started getting tons of errors like "the source file does not have attachment" and java.lang.StackOverflowError errors

I tried changing the build path of the project ( I thought that wrong build type is the reason ), but this didn't help. I thought that there is something wrong with the recursion, because of java.lang.StackOverFlowError, but there weren't any problems before I wrote the toString() method.

Was it helpful?

Solution

You are in recursive loop that never ends.

 String s = new String(""+this.neighbours);  

That goes to your list to print toString on each node.

Then into toString() again coming to list to print.

OTHER TIPS

As someone noted before, the "source file does not have attachment" error is the way Eclipse has to tell you that you have not told it where to find the .java file with which present you a debug view of your code when failing.

The StackOverflowError happens most probably when trying to call your toString override, which calls itself the toString override of every neighbour in the list. If there is any circular link between neighbours, this will lead surely to an overflow.

I propose you discard the idea of presenting a String with all the neighbours of a Node, which leads you to a recursive problem. Instead, if you must print something, try to write a transversal walk of the graph discarding visited nodes (or try to paint something with a 2D drawing API, but that would be another completely different problem)

I can explain the cause of the StackOverflowException

You are printing neighbours not children. If each neighbour has a reference to the other neighbour then you will constantly traverse backwards and forwards between those nodes.

Node n1;
Node n2;
  1. n1->toString scans it's neighbours which includes n2.
  2. n2->toString scans it's neighbours which includes n1.
  3. n1->toString scans it's neighbours which includes n2.
  4. etc until the stack overflow happens.

Normally nodes contain references to children, not neighbours. This code would work fine if you were scanning the children of the node at each step.

Incidentally this line is redundant:

    String s = new String(""+this.neighbours);  

All you need is:

 return ""+this.neighbours;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top