Tuesday, March 2, 2010

Proguard 4.x error - java.lang.ArrayIndexOutOfBoundsException - How to fix it

Using Proguard to obfuscate your classes in your midlets is a must. The jar size is reduced and the code is optimized.

But when I obfuscated my app an error is displayed and the jar is not obfustaced. The error is similar to:

java.lang.ArrayIndexOutOfBoundsException: 2

WTF is this? :)

I don't know why, I didn't download the source of proguard (BTW this amazing tool is opensource)

How to fix it? Two options:
* disable optimization. It's not the best option but it helps. Use parameter -dontoptimize
* disable optimization partially. I used this option. The last proguard has many parameters for optimization, and I found the parameter that worked in my midlet:

-optimizations !method/marking/static

this means the optimizer will avoid marking methods as static.

It worked for me, I hope it works for you.

Proguard optimizations site: http://proguard.sourceforge.net/manual/optimizations.html

Samsung - Java Error: Invalid Format. How to fix it.

There is a strange error in Samsung phones. When you try to launch a midlet the phone displays the message "Java Error: Invalid format".

Why?

This means the virtual machine can't load the classes of the midlet. It could be:
- the classes are not preverified
- the classes are corrupted
- the classes are ok but the VM can't load them, because an exception is launched while they are loading..

We will focus in the last option. Why a class can't be loaded and how to fix it?

- Sometimes we write some lines of code in the midlet constructor. But this lines can have method calls to other classes and so on, and all classes must be loaded BEFORE the midlet is initializad. If the midlet is not initialized it can't manage well things like screen.getWidth and getHeight, etc. Avoid method calls in the midlet constructor.
- Other cause can be to write method calls in static blocks or static variables. It's the same problem than before, lots of things must be loaded BEFORE the midlet is instantiated.

So, now the midlet is instantiated before the classes are loaded. Now the error "Invalid Formatd" shouldn't appear. Your phone must launch now an exception or anything similar.

E.g: Samsung S8000 Jet. This phone has a problem in some firmwares. The method Font.getSize() returns a non standard value, and when you want to obtain a new font using the size returned by Font.getSize() an exception is launched.  If this code is called by the constructor block an exception is thrown before the midlet is instantiated, so the error "Invalid Format" is displayed.

I worked with lots of samsungs and generally the solution is the same. Avoid coding in the constructor to find easily the errors.

I hope it works for you.

Cheers,

Lula