views:

232

answers:

4

I'm getting a NullPointerException in a Nokia S40.

I want to know what is causing this exception.

The device shows:

NullPointerException java/lang/NullPointerException

This error only occurs in the device, running in the emulator the application works fine.

I use microlog to debug my application. But the application works fine if the log is enabled.

Is there a way to get the stack trace when I get this NullPointerException? I don't need all details like the line number just which method cause this exception.

UPDATE: I installed the same application in another Nokia S40 and the same error didn't occur.

  • Nokia 2660 - error
  • Nokia 6131 - no error

UPDATE 2: Somehow I find what was causing the NullPointerException.

    import javax.microedition.lcdui.Canvas;
    import javax.microedition.lcdui.Graphics;

    public class OuterClass extends Canvas {

    private Config config;

    public OuterClass() {
     this.config = new Config();
    }

    public void paint(Graphics graphics) {
     HelperClass helper = new HelperClass(this.config);
     helper.doStuff();
    }

    public void dispose() {
     this.config = null;
    }

    public class Config implements IConfig {
     public int getSomething() {
      // ...
     }
    }
}


 public class HelperClass {

        private IConfig config;

        public HelperClass(IConfig) {
         this.config = config;
        }

        public doStuff() {
         config.getSomething(); // Here is thrown NullPointerException
        }
    }

In some situations a thread is started and call the OuterClass.dispose() before the helper.doStuff() causing the NPE. I think when I enabled the log it made the thread slower and helper.doStuff() was called when I expected it to be called.

A: 

You could try catching the exception in some high-level try/catch block and then emailing the trace to yourself.

Greg Mattes
I don't think there is a way to send e-mail from this device.
Daniel Moura
you can create a log file and write to it using jsr-75.
Orr Matarasso
When I write log via bluetooth using microlog the error doesn't happen.
Daniel Moura
Nokia S40 doesn't let you access a Throwable stack trace.
QuickRecipesOnSymbianOS
A: 

I had some trouble in the past trying to print the stack trace to somewhere else than the standard output. The standard exception class doesn't provide the printStackTrace method that receives the output stream, therefore it only prints to the standard output stream.

It's possible, at least in Java SE, to redirect the java output stream to somewhere else by simply saying that System.out = . The PrintStream class receives an OutputStream, which means that you could create your own ByteArrayOutputStream, initialize a PrintStream, sets System.out to that stream, and then call ex.printStackTrace(). I don't have a J2ME environment here but I believe that, as long as it won't break when you try to set System.out to something else (nothing says that it's readonly in the docs), you should be able to do it.

After you do that, I would recommend writing it to a RecordStore that you have specifically for that, and then upload the records of that RecordStore to your server so you can get it.

I know it's not very easy but it may work. I would first test the System.out thing. If it works, everything else should work too.

My answer was wrong. As pointed out, the System.out and System.err fields are declared final. If you can't get the stack trace, and if you can't get the error when running the application on your emulator, try creating trace bullets on your code (alerts, logs, whatever you can) to isolate the piece of code where the problem is happening. It has to be something that could change between the emulator and the real device - for example, something related to retrieving/ saving records in a RecordStore, opening a Connection, etc... What did you try to do when you had the problem?

Ravi Wallau
This is wrong, the MIDP docs say that both System.out and System.err are final. http://java.sun.com/javame/reference/apis/jsr118/
funkybro
+1  A: 

You are not going to find any way to save a Throwable stack trace on a Nokia Series40 handset.

The usual brute force way of debugging JavaME application on Series40 is to modify your code to create a stack trace yourself in memory.

What I'm talking about is:

  • Each Thread that you can identify (including system callback threads) needs its own Stack object, containing strings. Obviously, this increases the memory footprint of your application somewhat but keeping it in memory should limit the impact on race conditions.

  • When your code enters a method, it adds the method signature to the current Thread Stack. When the method exits (and you better only have one exit point per method) it pops the top of the Stack.

  • You can add aditional debug info on the stack, like values of variables in different places of the code.

  • You don't necessarily need to add this to every single method in your code.

  • You can add try{}catch(Throwable){} to the entry point of every thread you identified and either dump the stack in a file or on the screen (in a Form).

Obviously, this is not the kind of change you want to manually add in a lot of places in a large existing codebase. You can however make it part of your organisation coding standards for the future and write a source code parsing script to automatically add it to existing code.

QuickRecipesOnSymbianOS
A: 

You could use Microlog to send an e-mail when the exception occurs.

Johan Karlsson