1

In my code I get the above warning. Here is the part of the code where I get it,

try {
        fileFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
    } catch (URISyntaxException | NullPointerException e) {
    }
    finally {
        if (fileFile.getPath()!= null){
            strPathName = fileFile.getPath();
        }
        if (fileFile.getName() != null){
            strFileName = fileFile.getName();
        }
    }  

The line if (fileFile.getPath()!= null){ is the one with the warning. This code is not part of the Main class. It's in another class in another class file in the same package.

I'm not very experienced with programming but I believe I did nearly everything to prevent or catch a null pointer exception. Why do I still getting it and what can I do to get rid of it? Thanks for your help.

After reading all your hints I solved it. Here is the complete code:

public static ArrayList<String> getCurrentPath() {

    File fileFile;
    String strPathName, strFileName;
    ArrayList<String> arrPathFileName;

    strFileName = null;
    strPathName = null;

    try {
        fileFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
        if (fileFile.getPath()!= null){
            strPathName = fileFile.getPath();
        }
        if (fileFile.getName() != null){
            strFileName = fileFile.getName();
        }
    } catch (URISyntaxException use) {
    }     
    arrPathFileName = new ArrayList<>(); 
    arrPathFileName.add(strPathName);
    arrPathFileName.add(strFileName);

    return arrPathFileName;
}

As already mentioned I simply put the if statements into the try block and removed the finally block.

BTW is also tried to combine both if blocks into one that way:

if (fileFile != null){
            strPathName = fileFile.getPath();
            strFileName = fileFile.getName();
        }

But that produced a warning that fileFile will never become null. (what was my point of view from the beginning and so the warning "dereferencing possible null pointer" was really confusing me.)

6
  • 5
    catch (URISyntaxException | NullPointerException e) {}??? -- Never do this x 2. Seriously. You're 1) trying to catch a NPE which should never be done -- code that possibly has these is broken code and needs to be fixed, and 2) you're ignoring the catch block. Please read up on exception handling asap. Commented Aug 12, 2015 at 13:42
  • 1. `catch (URISyntaxException | NullPointerException e) {}' is what Netbeans suggested when I had a separate catch clause for each Exception. Commented Aug 12, 2015 at 14:14
  • 1
    This has nothing to do with NetBeans and all to do with again 1) NEVER catching NullPointerExceptions, and 2) NEVER ignoring exceptions with an empty catch block (with a few exceptions). I stand by my previous recommendation: read a tutorial on exceptions without delay. Commented Aug 12, 2015 at 14:17
  • 1) I fully agree, programm code should never cause a NPE. That was the reason why I added an aditional catch block for NPE which Netbeans the recommended to combine with the URISyntaxException catch block But my main goal is to write the code in such a way that a NPE cannot occur. 2) You are right, when thinking it over it's clear that what I added into the finally block made the catchblock useless. I had a printStackTrace command in the catch blocks. But again Netbeans recommended to remove it. Thanks for your comment. It was a little push into the right direction. Commented Aug 12, 2015 at 14:24
  • @Mike NetBeans likely recommended combining the two catch-blocks because they were not doing anything different. Also, catching a NullPointerException is not the proper way to write code without NullPointerExceptions (from looking I can tell you were probably just trying to fix the warning though). Commented Aug 12, 2015 at 14:31

2 Answers 2

10

So if you throw an exception on your first line, your variable will not be assigned to a File, and will retain it's previous value (null if not formerly assigned). Your exception is caught, and then you continue to use that unassigned variable. Hence the warning. See the commented code below.

try {
        fileFile = // exception thrown. Variable not assigned
} catch (URISyntaxException | NullPointerException e) {
        // exception caught
    }
    finally {
       // unassigned variable used here...
        if (fileFile.getPath()!= null){
            strPathName = fileFile.getPath();
        }
        if (fileFile.getName() != null){
            strFileName = fileFile.getName();
        }
    }  

I would rather scope and use the variable within the try block, if at all practical. In your finally block, you need to be as careful as you can, since you could have come to it from most anywhere in your try block.

As an aside, this:

Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();

will cause you enormous problems if you do get an NPE. Which of the above resolved to null ? I would perhaps be more explicit, such that you can check for nulls from each invocation and unambiguously determine which invocation gave you a null. Tiresome ? Unfortunately so.

Sign up to request clarification or add additional context in comments.

4 Comments

Let me nitpick as usual: is "unassigned" the correct term here? Since it is either a field and initialized with null or a local variable therefore already assigned somewhere else, it can't be "unassigned" at that point. But as I said, just nitpicking :D.
I take your point. I originally wrote 'uninitialised' and then replaced with 'unassigned'
@Brian I never really got a NPE, just the warning, The code always compiled and ran fine without errors. I moved the if statements into the try block, deleted the finally block and the warning is now gone. Thanks for your help.
@Brian and Tom fileFile is in fact declared in a declaration block at the beginning of the method, just declared, not initialized. So what you see in the code is the first use and initialisation of fileFile. it's almost 30 years ago when I learned some programming basics and Turbo Pascal was state of the art. So I still follow what Pascal required - a declaration block at the beginning of a programm/function etc. where ALL variables used in the programm/function etc. have to be declared and if possible initialized. From my point of view it makes it a little bit easier to read the code.
2

A "null pointer dereference" is computer speak for trying to call a method on a null value. It's a little more complicated, but you said you were a novice, so I wanted to keep it simple.

Let's see an example:

String s = null;
s = s.toUpperCase();

This is a simple example of what a null pointer dereference is. s is a null reference (its value is null), when we derefrence is (get the value of it) we have null, when we call toUpperCase() on null, something goes horribly wrong because null doesn't have any methods, at all! Java throws a NullPointerException to be specific.


Now, back to your code, because fileFile is assigned in the try-block I assume it was set to null before it to avoid Java yelling about an uninitialized variable. (This is all fine and correct.) In this try-block, if any of the exceptions for your catch-block occur it will stop the try-block (meaning fileFile will not get a new value, meaning it will still be null).

Now you'll notice the warning is possible null pointer dereference. That means it won't necessarily be null, but could be! (In my above example, it's always a null pointer dereference for comparison.) Specifically, if the catch catches an exception it will be null.

To be clear, the issue is this: fileFile.getPath(). It's like saying it might be null.getPath(), gross. It looks like you were trying to avoid the null pointer issue, what you should have done was if (fileFile != null) { instead. Then inside of the if do what you want.


Also, because it seems like you included it to avoid this warning, I would seriously remove the NullPointerException from the catch-block. That's not helping you avoid the warning. If you want me to explain more why it's bad you can leave a comment and I will, otherwise just take my word for it, it's not helping you.

3 Comments

Thanks for your your explanation how the NPE could occur. It gave me more understanding about it. However I believe thay way how I initialize fileFile makes it impossible to become null. I just want to get the path from where the compiled jarfile was called and that normally never can be a null value.
From what you're saying it wounds like you think the initializing is done in the try-block of your above code, this may or may not be the case. Declaring would be this File fileFile;, initializing is when you first assign a value (even if it's null) to it. If fileFile = ... is anywhere above your try block it's not being initialized there.
As far as Main.class.getProtectionDomain().getCodeSource().getLocation().toURI() never being null, I don't know, I've never done that before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.