ソフトバンクモバイル用のS!アプリ(MEXAアプリ)を作っているのだが、実機テストで「SH系で動くのにT系が全滅」という事態に遭遇した。前者は近年のdocomoと同じアプリックスのJavaVM、後者はSun由来のJavaVMを搭載しているんだそうだ。
最初に見つけた問題箇所は「整数演算するだけの関数」を呼び出す所。ゼロ除算してた...ではない。もちろん。docomoやSH系端末ではちゃんと動いてるロジックなのだ。いくらVMが違うからといって、こんな整数演算で差が出るのか?とりあえずコメントアウトしちゃえ。
...という所から始まり、徐々に徐々に停止箇所を追い込んでいった結果、「あるクラス」を参照しようとすると固まる事が判明。newしてもダメ、staticメソッドを呼んでもダメ。先の整数演算ロジックは、public final staticなintのメンバを参照していた。つまり、
犯人はヤスだ!(違う)
エエエエェェェェ!古くてすまん。つまり、jarの難読化ツール「ProGuard」が悪さ(実は悪いのはJavaVMなのだが)をしてたんですな。ProGuardかけないようにしたらあっさり動いた。ProGuardは数年にわたり同じオプションでトラブルなく運用していたので、最初に疑うべきポイントであったにも関わらずスルーしてしまった。
http://proguard.sourceforge.net/manual/troubleshooting.html
Failing midlets (on a Java Micro Edition device)
If your midlet runs in an emulator and on some devices, but not on some other devices, this is probably due to a bug in the latter devices. For some older Motorola and Nokia phones, you might try specifying the -useuniqueclassmembernames option. It avoids overloading class member names, which triggers a bug in their java virtual machine.
このように当該のトラブルは海外の古めのMIDP端末でも確認されているようで、上記の「-useuniqueclassmembernames」で難読化後のメソッド名をユニークにする事で解決した。この問題は「VMのバグに起因する」んですと。まじですかぁ。
iPhoneやAndroidと異なり実機でステップ実行もできず、バイナリを更新するたびにアップロードとダウンロードの操作が必要と、ガラパゴスJavaアプリのトライアンドエラーは面倒なことこの上ない。二日もかかった(汗)