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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With