August 2, 2009

openwig news

Version 0.3.92 is underway.
Biggest spectacle of this is cartridge saving and loading. A few moments ago i have successfully stored and restored a game of Wherigo Player Tutorial.
Technical details about the solution will follow in a separate article.
And that's pretty much it. There's the usual bunch of random bugfixes, minor improvements and extended Wherigo functionality (did i tell you that you can now see a zone map?), but probably nothing to write home about.

Oh, and i switched back from NetBeans' default proguard 4.2 (obfuscator/optimizer) to older 3.9. The new one is too aggressive in optimizing and still has some bugs. I identified and reported one, but it's not yet fixed, so i can't really continue the search. And i don't need the stress of hunting bugs that aren't there.

tidbits

S40 Nokias do weird things when you put a StringItem on a form, give it a label but no text. It will prevent users from scrolling that form.
S60 Nokias do some weird stuff too, but only sometimes. Best not to do this.

SonyEricssons, on the other hand, retain image size on ImageItem when you setImage(null). You have to set a dummy 1x1 image first (or instead).

And last but not least, with certain bluetooth devices (GPSr's, in this case), Nokia phone would perform a bluetooth service search, but return error instead of the service.
When you're searching for a serial port service (UUID 0x1101) and get an error instead, just take "btspp://" + RemoteDevice.getBluetoothAddress() + ":1" as a connection url and you have a solid chance of connecting successfully.
(That means BT address + channel 1. On single-purpose devices, you'll most likely find the only service on channel 1. Makes sense, eh?)

June 12, 2009

thoughts on Nokia class loading mechanism

situation:
Imagine you have your basic midlet class (say gui.Midlet). This class references another class (gps.InternalProvider) which implements a specific interface (gps.LocationService). Note that there is no reference to the actual class gps.InternalProvider, except for instantiation, and that is pretty well hidden in a function under several ifs and switches. Everything else is done through the interface.
Class gps.InternalProvider references classes from an api (JSR-179) that might or might not be present on your target device (S40 Nokia). It uses them rather extensively, but of course, it can't use them until it's instantiated. (no static codeblocks, nothing like that)

issue:
When such midlet is started on such device, it instantly dies with NoClassDefFoundError on the JSR-179 classes. It doesn't even start, I'm pretty convinced that none of my code is executed.
Definitely not the part that would instantiate the offending classes.

solution:
Create a distraction. Add a class (let's call it gps.InternalProviderRedirector) that has only one static method:
public static LocationService instantiate() {
return new InternalProvider();
}
Then instead of doing this directly in the Midlet class, call InternalProviderRedirector.instantiate(). Magically, it will work.

thoughts:
This is easy to grasp intuitively (for me, at least), but in some situations, that is not enough. So i studied the JVM specification, especially the parts about class loading and linking, and tried to come up with a scientific explanation to this phenomenon. Here's my best effort - note that it is only an educated guess and might not relate to reality in any way.

The spec says that when you are loading a class, you get symbolic references to all classes in use. Then, in the linking step, you can (but don't have to) resolve those symbolic references by trying to load the referenced classes.
I say that Nokia does this. That means that when linking the Midlet class, the class file for InternalProvider (or InternalProviderRedirector) is already loaded.
Then, either in the initialization phase or when the first code from a class is run, Nokia JVM attempts to link all the referenced classes. That means that those classes now try to load and resolve their symbolic references.
When you start the midlet, the class Midlet is loaded. Then it's linked, triggering loading of InternalProvider. And then it's instantiated, triggering linking of InternalProvider. That triggers loading of JSR-179 classes, which are not present, so the instantiation itself fails.
When you insert InternalProviderRedirector into the chain, InternalProvider is never linked (only loaded), so JSR-179 is never loaded. And all is well.

May 19, 2009

openwig news

Well well well. It sure has been a long time.
Today i have released a new and improved experimental version 0.3.90 (yup, that means pre-0.4), codenamed "Threadless". Why? Well, it's not because it makes t-shirts. It's because it doesn't use threads. Not too much of them, anyway.

Before this release, OpenWIG relied on threads for event synchronization. Whenever I needed to call an event handler, I spawned a thread that would perform the Lua code and die. Which is all good and nice, but can bring a lot of trouble. For one, when you use many threads, you need to care about (dead)locking. For two, some j2me implementations are somewhat inferior to the rest *cough*Symbian*cough*. Their garbage collection is simply not good enough. So it's better not to create too many objects, if you know what i mean.
Also, for the same reason, there is now a pre-allocated instance of each of the screen types (like "item details", "zone navigation", "dialog" etc.) and no new screens are created.

Oh, and screen switching is now stateless. That means that each screen knows in advance which screens can follow it. And that's cool! Lots of problems with screen refreshing disappeared this way.
And lot of them appeared. Oh well, for every bug you fix, three new are born.

In other news, we now have the latest and greatest Kahlua revision, which means that we support more obscure code. Inventories and AllZObjects are now accessible from Lua as tables. And some minor thingies, i don't remember exactly.

Anyway, the new version is very cool and you should all download it.

December 11, 2008

how to send JAR files to a Nokia from linux

Just so i don't forget next time.
  1. install gammu
  2. create a .gammurc:
    [gammu]
    # your phone BT address:
    port=00:02:5B:00:A5:A5
    connection=bluephonet
  3. cd /directory/with/jar/and/jad
    gammu --nokiaaddfile Application NameOfJarWithoutExtension

December 5, 2008

internal affairs filed under JSR179

OpenWIG 0.3.07 is out and it supports JSR-179 style "Location Providers" a.k.a. internal GPS.

Getting that to work was no picnic, though.

Here's a basic overview of how it's supposed to work:
  1. choose a list of things you want from your GPS device and set it all up in a Criteria object
  2. instantiate a LocationProvider by calling LocationProvider.getInstance(myCriteriaObject);
  3. periodically ask for a new location by calling provider.getLocation(timeout)
  4. or implement a LocationListener interface, and register that with the provider. You can then specify some refresh intervals and timeouts and whatnot. Fortunately, you can also leave it on default values.
Sounds rather easy, no?
Well, yes, but with a caveat: there's no listProviders or equivalent method. If the phone has more than one provider, it can return pretty much anything it wants.
And it turns out that e.g. Nokia N95 has more than one provider, and one of them is very dumb and coincidentally that's the one that is selected when you specify "empty" criteria (the default Criteria instance means basically "anything will do")

It seems to work when you say that you want to get speed, course, altitude and you allow it to cost money:
Criteria c = new Criteria();
c.setAltitudeRequired(true);
c.setSpeedAndCourseRequired(true);
c.setCostAllowed(true);
provider = LocationProvider.getInstance(c);
Oh and then there's the fun with invalid locations that can either have isValid flag set to false or be null. But that is easy to get right. Finding out that a phone is giving you a bad provider is the real pain.

November 24, 2008

what's cooking

Version 0.3.07, that's what. It will have all bugs from the previous post fixed, and its navigation arrow will be prettier and move smoother and just be plain old sexy.
Oh, and internal GPS's will be supported!
It will be ready sometime this week.

For the version after that, I intend to try and dig a bit into saving and loading. It won't be perfect, but maybe, just maybe, it will work well enough for most cartridges.

sidenote: there is a midlet called "OpenWIG-blackmagic" sitting silently in my phone. it has all kinds of very evil features that should never have been born. muhahahaa!

sidenote2: The name "OpenWIG" sucks. I need to come up with a different one.