A few days ago, I found another rare BlackBerry bug. I was playing with some list elements and everything was working fine until I ran the code on a BlackBerry Curve 8300.
I was suddenly presented with this popup.
I have never seen this error so I Googled for it. Unfortunately, there was no reasonable explanation. So I decided to investigate it. First thing I did was to take a peek at the event log. I did it by pressing ALT+L+G+L+G and I got this.
Taking a look at the exception trace showed this.
I needed to see the full log for details, so I used:
javaloader -u eventlog
To dump the event log (for this to work, you need to check the USB Cable Connected under the Simulate menu item of the emulator). My javaloader file is located at c:\eclipse_g_341_jde7\plugins\ net.rim.eide.componentpack4.5.0_4.5.0.14\components\bin\JavaLoader.exe.
The log looked like this:
guid:0x9C3CD62E3320B498 time: Mon Nov 23 15:05:00 2009
severity:1 type:3 app:Java Exception data:
IllegalStateException
ArticInterface::DocPosToCaret: error 3; formatted text length = 40;
net_rim_cldc-11
TextArea
getTextBounds
0x7B8E
net_rim_cldc-9
LabelField
layout
0x9D99
net_rim_cldc-8
Manager
layoutChild
0x1B98
net_rim_cldc-11
VerticalFieldManager
sublayout
0xC6F0
net_rim_cldc-8
Manager
layout
0x1A95
net_rim_cldc-8
Manager
layoutChild
0x1B98
net_rim_cldc-11
VerticalFieldManager
sublayout
0xC6F0
net_rim_cldc-8
Manager
layout
0x1A95
net_rim_cldc-8
Manager
layoutChild
0x1B98
net_rim_cldc-11
VerticalFieldManager
sublayout
0xC6F0
net_rim_cldc-8
Manager
layout
0x1A95
net_rim_cldc-8
Manager
layoutChild
0x1B98
net_rim_cldc-11
VerticalFieldManager
sublayout
0xC6F0
net_rim_cldc-8
Manager
layout
0x1A95
net_rim_cldc-8
Manager
layoutChild
0x1B98
net_rim_cldc-8
Screen
layoutDelegate
0x5375
net_rim_cldc-2
MIDPScreen
sublayout
0x9781
net_rim_cldc-8
Manager
layout
0x1A95
net_rim_cldc-8
Screen
doLayout
0x4B51
net_rim_cldc-8
UiEngineImpl
pushScreen
0xA538
net_rim_cldc-8
UiApplication
pushScreen
0x8A4B
net_rim_cldc-2
Display
switchDisplayables
0x3A60
net_rim_cldc-2
Display$SwitchDisplayablesRunnable
run
0x3FF5
net_rim_cldc-5
Application
dispatchInvokeLater
0xAAC
net_rim_cldc-3
MIDletMain
dispatchInvokeLater
0x4F78
net_rim_cldc-5
Application
processNextMessage
0x123D
net_rim_cldc-5
Application
enterEventDispatcher
0xA51
net_rim_cldc-3
MIDletMain
main
0x51FA
guid:0x97C9F5F641D25E5F time: Mon Nov 23 15:05:00 2009
severity:0 type:2 app:System data:JVM Error 104
guid:0x97C9F5F641D25E5F time: Mon Nov 23 15:05:00 2009
severity:0 type:2 app:System data:Uncaught: IllegalStateException
The event log shows a very interesting thing. It seems the J2ME list is rendered as a VerticalLayout
that contains Labels
.
We start by looking for TextArea
. We cannot find it in the SDK so we look for the LabelField
class. We find the LabelField
in C:\eclipse_g_341_jde7\plugins\net.rim.eide.componentpack4.5.0_4.5.0.14\components\lib\net_rim_api\net\rim\device\api\ui\component\LabelField.class.
A quick look in the documentation of LabelField
shows us the setText
method can truly throw an IllegalStateException
.
public void setText(Object text)
Sets this field's label text.
Parameters:
text - Label text which may be a string, string buffer, character array,
or byte array (may be null for an empty label).
Throws:
IllegalArgumentException - if text parameter is an unsupported type.
Source: BlackBerry JDE 4.5.0 API Reference: Class LabelField
Looking for the getTextBounds
method gives us a few results, like C:\eclipse_g_341_jde7\plugins\net.rim.eide.componentpack4.5.0_4.5.0.14\components\lib\net_rim_api\net\rim\device\internal\ui\Formatter.class c:\eclipse_g_341_jde7\plugins\net.rim.eide.componentpack4.5.0_4.5.0.14\components\lib\net_rim_api\net\rim\device\api\ui\component\TextField.class
The method signature looks like:
getTextBounds(IILnet/rim/device/api/ui/XYRect;Lnet/rim/device/internal/ui/ArticInterface$Line;II)
Since the TextArea
is not available and the ArticInterface
is also missing, we must move our search somewhere else.
What we can notice is the exception thrown has something to do with the caret - DocPosToCaret
.
After a little bit of testing, I was able to reproduce the bug. It seems the bug appears when the list item contains a ‘\n
’ char right in the beginning of the text and the text following will be long enough to need to be split on different lines.
Also, setting many ‘\n
’ char
s in the beginning will make the exception pop up for a smaller following text length. Unfortunately, without the code, we cannot say exactly how the algorithm in getTextBounds()
works, but still, we now have a good picture of why this happens and how it can be avoided (for example, by removing the ‘\n
’ chars from the beginning of the text, or by adding a space “ “ char in front of the text).
Some tech details:
- This behavior only seems to exist in
net.rim.eide.componentpack4.5.0_4.5.0.14
and not other emulators.
- The bug appears on the BlackBerry Curve 8300 phone.
- You can download the code to reproduce the bug here ws_DocPosToCaretException.zip (599.40 KB)
- The emulator specification looks like this:
I hope you have enjoyed this rare to find bug, and if you want to see another one, a really funny one, then please also check this one here BlackBerry - This is sexy, isn’t it?.