views:

99

answers:

3

After compiling my application in Netbeans and running the application in Netbeans it works just fine.

All images load fine.

Trying to double click execute the application results in nothing happening.

Trying run from command line gives this error:

Exception in thread "main" java.lang.NullPointerException
     at Entity.<init>(Entity.java:24)
     at Actor.<init>(Actor.java:5)
     at TileEngine.drawMap(TileEngine.java:52)
     at GraphicsCanvas.<init>(GraphicsCanvas.java:32)
     at Main.<init>(Main.java:22)
     at Main.main(Main.java:18)

Compiling outside of Netbeans leaves no errors and execution is fine.

After trial and error of commenting I've came to these the anonymous call to Actor that is causing the problem. Here is function of the code that when commented out does not throw the exception. I cant seem to find anything wrong with it.

public class Actor extends Entity
{
    Actor(String filename, int x, int y)
    {
        super(filename, x, y);
    }
}


void drawMap(String imgWalkable, String imgNotWalkable, GraphicsCanvas gp)
    {
        // Since each 1 tile is a tile that can be walked on
        // we need to set the 1 tile to something you can walk on.
        // The tiles that cannot be walked on are the ones that are 0

        for (int x = 0; x < WID; x++)
        {
            for (int y = 0; y < HEI; y++)
            {
                if (GRID[x][y] == 1)
                    gp.add(new Actor(imgWalkable, x * TILE_WID, y * TILE_HEI));
                //else
                    //gp.add(new Actor(imgNotWalkable, x * TILE_WID, y * TILE_HEI));
            }
        }
    }

I have further traced this error to BufferedImage in my Entity class.

public class Entity extends JLabel
{
    Entity(String filename, int x, int y)
    {
        this.x = x;
        this.y = y;
        this.setLocation(this.x, this.y);
        bImg = loadImage(filename);
        this.setSize(bImg.getWidth(), bImg.getHeight());
        ImageIcon icon = new ImageIcon(bImg);
        setIcon(icon);
    }

    public BufferedImage loadImage(String filename) {
        BufferedImage tmp = null;
        try {
            tmp = ImageIO.read(getClass().getResource(filename));
        } catch (Exception e) { }
        return tmp;
    }
}

After removing loadImage function and instead loading the image like this:

Entity(String filename, int x, int y)
    {
        try {
        bImg = ImageIO.read(getClass().getResource(filename)); //LINE 25
        } catch (IOException ex) {
            Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.x = x;
        this.y = y;
        this.setLocation(this.x, this.y);
        //bImg = loadImage(filename);
        //loadImage(bImg, filename);
        this.setSize(bImg.getWidth(), bImg.getHeight());
        Icon icon = new ImageIcon(bImg);
        setIcon(icon);
        setVisible(isAlive);
    }

This new error is received:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: input == null!
     at javax.imageio.ImageIO.read(ImageIO.java:1362)
     at Entity.<init>(Entity.java:25)
+3  A: 
Entity.<init>(Entity.java:24)

This tells you that the exception is being thrown at line 24 of "Entity.java". YOU DON'T TELL US WHICH LINE THAT IS (tsk, tsk, tsk!!) ... but I expect it is this one:

this.setSize(bImg.getWidth(), bImg.getHeight());

and that it is happening because loadImage is returning null.

Another problem (though not the cause of the NPE) is that the following line uses this.x and this.y before they have been initialized. In fact, the constructor doesn't initialize them at all!!

Yet another problem is that your loadImage method is explicitly coded to catch and ignore exceptions, and return null. So basically, if the image read does fail for any reason, you will never know about it. This casts considerable doubt on your assertion that the image is being successfully loaded. And even if this is not the cause of your problem, squashing exceptions like that is extremely bad practice.

this.setLocation(this.x, this.y);

EDIT

The problem is now in this line:

bImg = ImageIO.read(getClass().getResource(filename)); //LINE 25

and the problem is that getClass().getResource(filename) is returning null and passing it to ImageIO.read which is throwing the NPE as a result. The javadoc for Class.getResource(String) says that the method returns null if the resource cannot be found.

THAT is your problem. If you don't believe this diagnosis, add some traceprints to see what getClass().getResource(filename) actually returning.

Stephen C
That doesn't make sense because the image is being loaded
@mOOst - well 1) you haven't told us what line 25 is and 2) that's what the evidence that you have given us seems to point to.
Stephen C
I forgot to include the code for init'n x/y. The problem is not the loadImage function. The problem lies in ImageIcon itself. I'll update the post.
@Stephen C: Completely removed loadImage and attempted to load without loadImage. Look at new code and you'll see the new error.
After debugging I notice that bImg is always null EVEN after successfully loading an image.
Stephen C: That is the problem; however there has to be a glitch in Netbeans for NB to load the images. Then outside of the class such as executing the JAR not load them with NPE.
@mOOst - it is most likely an issue with the *effective* classpaths being different when you run the code in NetBeans and free-standing. Also, review @John D's answer. That might be the root cause.
Stephen C
+1  A: 

Is the fileName being passed to loadImage a relative path? If so, it could successfully load the image from within the IDE but not from outside it. That would let the file load correctly within the IDE but may result in a null pointer exception from other environments. If that is the case, using an absolute path may fix the issue.

John D
All images load fine
Have you verified that in all environments? The images loading inside the IDE does not mean they do outside it. getResource(filename) could leave you with it working in some environments but not others. For instance, maybe NetBeans is making the working directory be a specific point in your project. A command line invocation wouldn't do that. The code you posted doesn't include any extra checks you may have. Have you tried checking to see if tmp is null immediately after assigning it.
John D
@John D: I'm using relative path loading. Yes I checked tmp and it stays null; but like I said images are being loaded which doesn't make sense.
A: 

If you use getResource(), like you are doing in the line where the error now happens:

bImg = ImageIO.read(getClass().getResource(filename));

then Java will look for the file to load on the classpath. What does filename contain? Is it in the right place so that it can be found relative to the classpath?

Also, catching and ignoring exceptions, as you're doing in your Entity.loadImage() method:

try {
    tmp = ImageIO.read(getClass().getResource(filename));
} catch (Exception e) { }

is one of the worst sins you can commit as a Java developer. Don't do that; at least log the exception, handle it some other way, or declare that the method it happens in throws it. For example:

// Declare that the method might throw IOException
public BufferedImage loadImage(String filename) throws IOException {
    // ...

    // No need to try / catch the exception now
    tmp = ImageIO.read(getClass().getResource(filename));
}
Jesper