Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the null in a method invocation chain

I am looking for a quick way of figuring out what part of a chain is null.

An example to illustrate the point:

public class Chain {
    private Chain chain;

    public Chain returnChain() {
        return chain;
    }

    public void addChain(Chain chain) {
        this.chain=chain;
    }

    public String toString() {
        return "Hello!";
    }

    public static void main(String[] args) {
        Chain c1 = new Chain();
        c1.addChain(new Chain());

        System.out.println(c1.returnChain().returnChain().returnChain().returnChain());
    }
}

This will obviously throw a NullPointerException. (I know how to alter the code to make it obvious what part of the chain threw the NullPointerException, but I would like some way of figuring it out with existing code.)

like image 417
Christian Neverdal Avatar asked Oct 08 '22 20:10

Christian Neverdal


2 Answers

In the stack trace for a typical NPE, you're given the line number it occurred on. So assuming System.out.println(c1.returnChain().returnChain().returnChain().returnChain()); is on line 144 (just picked that randomly) your NPE stack trace should look something like:

java.lang.NullPointerException
  at your.package.Chain(Chain.java:144)

So, if you put your chain call on multiple lines, it should show you where the exception is.

I wrote up this little example:

package bla;

public class Something {
    public static int count = 0;
    public Something get() {
        if(count == 2) {
            return null;
        }
        ++count;
        return new Something();
    }

    public static void main(String[] args){
        Something something = new Something();
        Something test = something.get()
                                .get()
                                    .get()
                                        .get() // Should throw NPE
                                            .get()
                                                .get();
    }
}

And it gave me the NPE says: at bla.Something.main(Something.java:18) - exactly where the NPE occurred in the chain.

Screen shot...

Showing what this would look like...

like image 182
Dave Avatar answered Oct 12 '22 03:10

Dave


For the particular piece of code that you have, try adding the following method to your Chain class:

    public static Chain checkChainSequence(Chain first, int count) {
        Chain thisChain = first;
        StringBuilder out = new StringBuilder("firstChain");
        for (int i = 0; i < count; i++) {
            Chain nextChain = thisChain.returnChain();
            out.append(".returnChain()");
            if (nextChain == null) {
                out.append(" returned null");
                System.out.println(out);
                return null;
            }
            thisChain = nextChain;
        }
        return thisChain;
    }

You can use it as follows:

    Chain c1 = new Chain();
    c1.addChain(new Chain());

    // To check c1.returnChain().returnChain().returnChain():
    Chain.checkChainSequence(c1, 3);

This would print:

    firstChain.returnChain().returnChain() returned null
like image 36
Dawood Avatar answered Oct 12 '22 02:10

Dawood