aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Tricky NullPointerException Problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Tricky NullPointerException Problem" Watch "Tricky NullPointerException Problem" New topic
Author

Tricky NullPointerException Problem

colin shuker
Ranch Hand

Joined: Apr 11, 2005
Posts: 744
Hi,

I've got a problem with my image handling in an application.
It works perfectly fine on my pc, but on my friends pc, there is a NullPointerException
happening when it tries to use:
createLargeImages(String folder) <--- Loads 6 Large images in for each face of cube
createSmallImages(int W) <--- Splits each of the 6 large images into 9 small ones

The point is, these two methods work fine when he uses the button to load in a new set of 6 large images,
its just the first call to them (in Main class constructor) that gives a NullPointerException

I'm thinking the createSmallImages(int W) is possibly being called before the createLargeImages(String folder) completes,
resulting in the exception

Basically, after I jar the application, there is an "images" folder(in same directory as jar file),
the images folder contains several subfolders (any names can be used for these folders, these names become JMenuItems)

Below is the Main class:



And the Images class is here:




Sorry for the big amount of code, but I thought I should include it for clarity.
If anyone can understand why I get a NullPointerException (see ** in Main class)
that would be great.

Thanks for any advice.
[ April 08, 2007: Message edited by: colin shuker ]
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39409
    
  28
Please post the whole stack trace. I am not at all convinced you have got the location of the NullPointerException right.
This problem is so common I think there ought to be a NullPointerException FAQ .

NullPointerExceptions occur in certain circumstances:-
  • When you have declared an object and not instantiated it.
  • When you have "lost" an object, maybe a transient field which has been serialised and not reconstructed on de-serialisation.
  • You have mistakenly set an object equal to null
  • You have mistakenly passed a null reference when an object is called for.
  • When you say "throw new NullPointerException();" or similar.
  • And there are probably others. There is no way you can have a null reference in a line likeCheck for everything I have suggested in the list. Get the highest line you can find where the stack trace shows something you have written yourself. Find every object mentioned in that line/statement. If you have access to a debugger, put a breakpoint on that line, and when you get there inspect every object mentioned in the line, to make sure it is not null.
    If you don't have a debugger, count all the objects mentioned in that line, and insert a line rather like this immediately before it:-Make sure every object you can see in that line is included. If you get a printout of something incomprehensible, assume you actually have an object there. If it is null, it will say "Object 3 = null".
    If that doesn't work, go up the stack trace to an earlier line and repeat the whole procedure.

    Where have you instantiated your largeImages[] and subImages[] arrays?
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 39409
        
      28
    . . . and please confirm that your friend has the images in the correct folder for your app to find.
    colin shuker
    Ranch Hand

    Joined: Apr 11, 2005
    Posts: 744
    My friend has images in correct folder, because when he clicks on a button, he can load which ever set of 6 images he wants, using those 2 methods:
    createLargeImages, createSmallImages.

    So thats not the problem, its the first call in the constructor to call these 2 methods to load them in.

    I've used try catch blocks, and the NPE is coming from createSmallImages code, but I don't know why.

    I can't print a stack trace or anything, because there is no error on my pc, just on his, he doesn't understand java, or have an IDE, I just send him the jar files, and he runs them, the only way I know the NPE is coming from there is because I have got the details to show up on a JLabel, but this is extremely tedious and frustrating trying to fix a problem that you don't have by running it on someone elses computer by displaying the error through the GUI.

    Thats why I'm having to ask at the forum, is this a threading issue?
    Perhaps I need to use SwingUtilities.invokeAndWait(Runnable runnable), but I have tried it a couple of ways, and its still causing an error.

    The largeImages and subImages are instantiated each time createLargeImages and createSmallImages are called.


    Any more ideas?
    Thanks
    [ April 08, 2007: Message edited by: colin shuker ]
    Craig Wood
    Ranch Hand

    Joined: Jan 14, 2004
    Posts: 1535
    This line in the Images class is probably comming up with the NullPointerException

    Why? In the Main class you have

    where each line creates a new instance of Images. Yet the Images class is designed for single-instance use. The second instantiation of Images calls createSmallImages which needs the largeImages array to have been created. But in a new instance of Images this array will be null. So try:

    Another (so far, unrelated) thing to look out for is this line

    the getScaledInstance method is asynchronous: it may return before its data is loaded.
    colin shuker
    Ranch Hand

    Joined: Apr 11, 2005
    Posts: 744
    I initially was using images.createLargeImages(), and images.createSmallImages(),
    But I thought I would try it without Saving an Image instance...
    But the 2 arrays in the Images class are static, so it shouldn't matter how many instances I use.

    You are absolutley correct about the null pointer exception coming from the line

    I forgot to mention that earlier, but pixels is coming out as null.

    But not null on my pc, so I'm not sure if the images on my friends computer are not being saved to the largeImages field in time for when createSmallImages is called, or if there is a problem with grabPixels() method.

    I guess inside the grabPixels method, I could test if the argument (Image image) is null or not.

    Any other ideas? Thanks
    colin shuker
    Ranch Hand

    Joined: Apr 11, 2005
    Posts: 744
    Hi again, I've found the problem, and it is what I suspected.
    The createSmallImages() method is being called before the createLargeImages() method completes.

    So in my constructor, I have:


    So I need the code above to be executed in order, but I'm not sure if I should start a new Thread, to do this, please can you help me work out the best way to execute the above code in that order.

    Thanks very much for everyones help.
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 39409
        
      28
    Try something simple first. Try synchronizing the createLargeImages and createSmallImages methods.
    Alternatively, try a "Thread.sleep" between the two calls.

    See whether those suggestions make any difference.
    Craig Wood
    Ranch Hand

    Joined: Jan 14, 2004
    Posts: 1535
    So I need the code above to be executed in order, but I'm not sure if I should start a
    new Thread

    I don't think a new Thread would help with the execution order but could be useful if the
    image loading/subdividing took a long time — doing it in a background thread would leave
    the gui responsive. May not be a problem.
    please can you help me work out the best way to execute the above code in that order
    I had trouble downloading your jar file so I made up some images and tried out your code.
    Your original syntax new Images().createXXX worked okay, no exceptions.
    The design seems to have problems in two (related) areas: possible state confusion and
    potential sequencing difficulties.
    The first problem area seems to be that since the arrays are static you have to be careful
    when and where you change/access them; there can be uncertainty about their state at any
    time. To avoid this I tried eliminating everything static and set it up it for
    one–time/instance use.
    The second problem area (which you mentioned) seems to be calling the separate methods
    from outside the class. To eliminate this I changed things so we could tell the class what
    we want and have it return the subImages, handling the scheduling on its own.
    I decided to leave in the helper_image_making method in case you wanted to use it for
    testing. If so, be careful that the hard–coded path doesn't overwrite anything.
    colin shuker
    Ranch Hand

    Joined: Apr 11, 2005
    Posts: 744
    Excellent stuff!!!

    I've made the same changes to my program, and it still works, I'll have to wait till tomorrow before I can test it on my friends computer.

    Before the only way I could get the
    createImage(new MemoryImageSource(...)) to work, was to extend JPanel, but using that toolkit is much better.

    Thanks for taking time to look at my code, I know its unappealing trying to work with a chunk of someones code, and trying to figure out what its purpose is, but I think you understand my code better than me!

    Thanks again, I'll let you know how I get on when I run it on friends pc.
    colin shuker
    Ranch Hand

    Joined: Apr 11, 2005
    Posts: 744
    Hi...

    I modified my code accordingly, but my friend Jeff is still getting an error on his pc, but now it seems that createSmallImages() isn't called
    at all.

    The code called from the constructor of Main class:


    Also in main class, I create a static field String X="";
    Inside the createImages method, output is added to X,
    then X is displayed in the GUI (Note, I can't easily test this, since there is no error on my pc, and my friend doesn't have a clue about how to fix it on his pc).

    Here is all of the Images class:


    On my pc(where it works!) X comes out as...
    "LSL0L0L1L1L2L2L3L3L4L4L5L5LFsSs0s0s1s1s2s2s3s3s4s4s5s5sF",
    Which follows exactly the order of execution.

    On my friends pc(where it doesn't work) X comes out as...
    "LSL0"

    So it seems the exception is being thrown here:


    But this doesn't make sense, since if he presses a button to load in a new set of images, then this method is called, and there is no problem.

    I'm totally stumped with this, I don't see how it can cause an exception when called in the constructor, but work fine when a button invokes it.

    Any ideas? Thanks
    Craig Wood
    Ranch Hand

    Joined: Jan 14, 2004
    Posts: 1535
    if he presses a button to load in a new set of images, then this method is called, and
    there is no problem.

    I don't see anything that might be causing this and haven't been able to replicate it.
    Let's open things up a bit and see if we can get some indication of what's messing us up.
    Changes to ImagesTest:
    colin shuker
    Ranch Hand

    Joined: Apr 11, 2005
    Posts: 744
    Thanks Craig, great work!

    I had to modify the filepath slightly, eg if you have a set of
    6 cat pics, they would be in "Cats" directory, so the filepath would be
    "images/Cats/pic0.jpg" and so on...

    Anyway, I emailed Jeff the new Jar file, and he sent me the value of X, and this is what I got...

    CLI:f= .DS_Store con NULLpath[0] = images/.DS_Store/pic0.jpg
    LDSTS=4 W=-1 H=-1
    CLI ERR:java.lang.IllegalArgumentException: Width (-1) an(bit missing here)

    At first I thought it was a typo, but it seems he has a subfolder of images called ".DS_Store", because its there twice.
    He is using a Mac, and its possible to use "." in a Mac, but on my pc, I wasn't allowed to start a file using ".".

    As you can see, the file.list() returns NULL, so quoting the File.list() from the Java 1.4 API...

    Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.

    I don't think it could have been an error since more data was added to X meaning the code continued executing, so 'file' was not a directory.

    So hopefully thats the solution, and perhaps the other folders he named didn't start with ".", so that calling createImages(folder,W) works fine.

    He won't be on for 8 hours, but I'll get him to try it with a new subfolder name.

    Does the above make sense?
    Thanks
    colin shuker
    Ranch Hand

    Joined: Apr 11, 2005
    Posts: 744
    OK, you can ignore that last post, he didn't create a subfolder inside images, called .DS_Store, MAC OSX automatically generates these invisible files, so instead of reading in the folder name "Cats", it reads in the file name ".DS_Store", which of course has no pictures inside it.

    So I just need to write code to ignore these files.
    Thanks for everyones help.
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Tricky NullPointerException Problem