Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

Sign up now!

Question Best way to deal with methods that can throw NullPointers

Joined
Jun 25, 2019
Messages
24
So I'm finding that with a lot of my code it will work 98% of the time and then after an hour or two it will throw a NullPointers exception. Even if I do a Null check beforehand eg:

Code:
LocatableEntityQueryResults<Npc> nearestNpc = Npcs.newQuery().names("Some Npc").results().sortByDistance();
try {
    for (Npc npc : nearestNpc) {
        if (npc.getTarget() != null) {
            if (npc.getTarget().equals(Players.getLocal())) {
                if (Players.getLocal().getTarget() != null && Players.getLocal().getTarget().equals(npc)) {
                    break;
                } else {
                    npc.interact("Attack");
                    break;
                }
            }
        } else if (Players.getLocal().getTarget() == null) {
            getLogger().info("Attacking npc");
            if (npc.getAnimationId() != 1190 && npc.getAnimationId() != 1184 && npc.getAnimationId() != 1186) {
                npc.interact("Attack");
                break;
            }
        }
    }
} catch (NullPointerException e) {
    getLogger().warn("Threw null pointer trying to attack");
}

So in this snippet there is the odd occassion where the npc is not null and then maybe it gets killed by another player and throws an exception when i try to interact with that npc. Another example is if im looting and the item isn't null when i search the area for it and then when i go to click(); it someone has already picked it up and a NullPointer has been thrown.

Other than using a try catch statement, is there any other good pattern that I could used in any bit of code that might throw a NullPointer?
 
Last edited:
The Omen
Joined
Dec 27, 2018
Messages
159
First things first, please can things before you go into a long-winded nested-if block of code. Store your local player, nullcheck it, then carry on if its not null. The reason you're getting nullpointers in your code if because every time you call something like `Players.getLocal` or `npc.getTarget()` it's re-querying for that player or target which may be null at that time.

Secondly, for (almost) every entity there's a query builder. GameObjects, Npcs, Interfaces, etc. Make use of those as they have builders that will help you massively reduce your lines of code and increase readability. For example your code could be reduced to 1 line in the form of
`Npc target = Npcs.newQuery().targeting(Players.getLocal()).results().nearest();`

You can even query for the person targetting a specific Npc by doing `Player player = Players.newQuery().targeting(npc).results().first();`. All your answers are in the jdocs at Generated Documentation (Untitled)
 
Joined
Jun 25, 2019
Messages
24
Cheers for the advice. I've updated my original code to be more clear as I think it caused some confsuion which you have shown me in your response(Npc query filter).

I have tried assigning the npc to a variable and the code still throws null pointer exceptions. This is because it doesn't matter if you store it in a variable becuase when the .click(); method is called the object it's referencing(dead npc or looted item) doesn't exist.

This code is an attacking method, the reason I don't store things in a variable is becuase I wan't everything checked and calculated in real time, hence why I make the method call again and not reference something older stored in a variable.

Hopefully this clears things up, it still doesn't help me find a common patteren used by bot authors here to deal with code that can throw null pointers other than using a try catch
 
The Omen
Joined
Dec 27, 2018
Messages
159
Cheers for the advice. I've updated my original code to be more clear as I think it caused some confsuion which you have shown me in your response(Npc query filter).

I have tried assigning the npc to a variable and the code still throws null pointer exceptions. This is because it doesn't matter if you store it in a variable becuase when the .click(); method is called the object it's referencing(dead npc or looted item) doesn't exist.

This code is an attacking method, the reason I don't store things in a variable is becuase I wan't everything checked and calculated in real time, hence why I make the method call again and not reference something older stored in a variable.

Hopefully this clears things up, it still doesn't help me find a common patteren used by bot authors here to deal with code that can throw null pointers other than using a try catch
You have still done it wrong. Call ".first()" on your query results to get the npc that's targetting you. You're also probably getting nullpointers on your Players.getLocal() stuff. Call it once at the start of your method, cache it in a variable, then use that variable for references later in the method.
 
Joined
Jun 25, 2019
Messages
24
You have still done it wrong. Call ".first()" on your query results to get the npc that's targetting you. You're also probably getting nullpointers on your Players.getLocal() stuff. Call it once at the start of your method, cache it in a variable, then use that variable for references later in the method.

Sigh I still don't think you are properly understanding me.

How does calling .first(); change the fact that the object im trying to interact with might still be null(dead npc, item that has been looted by someone else) and throw a Null Pointers exception? Using .first() also wouldn't be good as I want to grab all the npc's in the area and filter them. I can't do this with the query builder filters so I run them through a few if statements. I have included all my code above so hopefully it makes it more clear what im doing and why im doing it.

Also calling Players.gerLocal() should never return null if the player is logged in, so it shouldn't throw a Null pointer exception and storing this in a variable wouldn't change that.
 
The Omen
Joined
Dec 27, 2018
Messages
159
Players.getLocal() can occasionally return null, that's why it's marked as nullable and requires appropriate null-checking.

Try this, this filters Npcs being targeted by you or no one else.
Code:
Player local = Players.getLocal();
if (local != null) {
    Npc target = Npcs.newQuery().names("Some npc").targetedBy(local, null).results().sortByDistance().first();
    if (target != null) {
        target.interact("Attack");
    }
}
 
Joined
Jun 25, 2019
Messages
24
Players.getLocal() can occasionally return null, that's why it's marked as nullable and requires appropriate null-checking.

Try this, this filters Npcs being targeted by you or no one else.
Code:
Player local = Players.getLocal();
if (local != null) {
    Npc target = Npcs.newQuery().names("Some npc").targetedBy(local, null).results().sortByDistance().first();
    if (target != null) {
        target.interact("Attack");
    }
}

Yup so I had something like that originally. It didn't work as well becuase the npcs im fighting are agressive. So i do a few checks to see which Npcs around me are trying to fight me and find which one is closest and attack that one, if none are found then just attack the closest.
 
Top