Archive for the ‘JavaME’ Category

Touch Buttons: the Optimal Shape and Size

Tuesday, May 20th, 2008

While physical buttons were the standard for mobile phones in the past, it seems that the industry is gradually adopting touch-screen interfaces. The iPhone is the best example of a touch interface, but other manufacturers (e.g. Sony-Ericsson, Motorola) are also producing mobile phones with touch-screen interfaces (either exclusively touch-screen, or in addition to physical keys).

Talking about the physical keys, we can imagine that their design, shape and size was the result of elaborate ergonomic studies in order to make them as easy to use as possible (hoping that the trendy look of the device was not the only factor deciding the design of the keys).

Perhaps taking inspiration from the physical keys, the touch buttons usually have a rectangular shape (sometimes with rounded corners). But is the rectangular shape the best one? and if it is, which is the best width/height ration of the rectangle (e.g. a horizontal rectangle, a vertical one, a square, etc). Of course, the answer may depend to some degree of the particular device and the particular user, but perhaps there are also general characteristics of a good touch-screen button shape/size.

I describe below a simple experiment which allows to discover the optimal shape/size. Ask the user to touch a specific spot (’target spot’) on the screen, and record the place where the touch actually occurs. Repeat this many times. Afterwards, you can visualize the area where the actual touches occur, which likely is a shape around the target spot.

This area, the place where the actual touches occur when the user is trying to touch the target, describes the optimal shape of a touch button. It gives information about the size of the button — it should be large enough as to embed the area of the actual touches, and about its shape.

I expect that the touch area resulting from such an experiment describes an ellipse (a ‘flattened circle’). While this is not a big surprise (as it’s normal that the actual touch occur ‘around’ the target, and the ellipse is the generalization of a circle), there is valuable information in the ratio of the ellipse (how flattened it is), and in its size. While the ellipse can be covered with a rectangular button, the rectangular ratio should follow the ratio of the ellipse.

Arity Performance on Mobile Phone vs. Desktop Computer

Thursday, March 27th, 2008

I’m so happy I’m blogging again!

So, everybody knows already that I am the author of the Arity Arithmetic Engine, a nice little open-source library for evaluating arithmetic expressions. In this library I put quite some attention on the elegant and minimal code, and on performance. The functionality is mainly split in two parts: compiling an expression (takes a string and returns a Function object), and evaluating the Function.

For example, compiling the string “g(x)=x^2″ produces a Function instance. Calling eval(5) on this function returns 25. These two operations (compilation and evaluation) are separated because you typically compile an expression once, but evaluate it many times (for example when plotting the graph of a function).

On a desktop computer, Arity can do about 50,000 compilations/second, and about 1,000,000 evaluations/second. So the compilation is about 20 times slower than the evaluation.

Why is the compilation so slow? well, you may be surprised, but the bottleneck during compilation is the parsing of a double value from a string (using the java.lang.Double.parseDouble(String)).
And Double.parseDouble() is not only slow, it also does quite some memory allocations (which again result in slowness when the GC is invoked to collect that memory).

One key advantage of the Arity library is that it compiles not only on JavaSE (desktop Java), but also on JavaME/MIDP (mobile Java). So last weekend I decided to measure its performance on my mobile phone (a modest Nokia 6300). I wrote a tiny midlet for the benchmark, and the result is:

On the mobile phone, Arity does about 500 compilations/second, and about 10,000 evaluations/second. So the 20 times factor between compilation and evaluation speed is the same as on desktop.

And the key information, the mobile phone is about 100 times slower than the desktop computer (from Arity’s point of view).

Still, 10,000 evaluations/second on the mobile phone is not bad, I am quite happy with this performance.

PS: go check out Arity: http://arity.googlecode.com/

Menstral and Javia Calculator become open source

Saturday, March 17th, 2007

I have just made available the source code for my projects
Menstral and Javia Calculator under the liberal MIT License.

To get the source code you need a subversion client.
The svn repositories are here:
Menstral Source Code and
Javia Calculator Source Code.

Enjoy,
Mihai

Going open source?

Friday, March 2nd, 2007

I’m thinking about open-sourcing my two JavaME (mobile phone) projects, Menstral and Javia-Calculator.

My reserve to open source them until now was caused mainly by a hope to transorm these projects in a commercial offering at some point. So my recent inclination to open-source them also means that I’m not planning to make any money from these projects anymore.

The main reason for open-sourcing is to allow the programs to evolve (bug-fixes & enhacements) even as I have less time (and inclination) to do everything myself. Of course I’m aware that just open-sourcing a project doesn’t automatically create a community around it, and this is the open-source challange.

I have to choose a code repository (SVN). The choices I consider are: SourceForge, Google Projects, and self-hosted. Self-hosted is more work, but also allows for the greatest flexibility.

Considering the license: MIT or GPL? I personally like the MIT license more, as I consider it less restrictive (and much shorter) than GPL. On the other hand, GPL protects against the possibility of competitor closed-source projects freely taking advantage of the code.

Carnival of the Mobilists at Mobbu

Monday, January 29th, 2007

Mobbu is hosting this week’s Carnival of the Mobilists, check it out.

Midlet Signing

Wednesday, January 24th, 2007

Disclaimer: this article is in draft state, I plan to come back and improve it upon checking the facts, so take it with a grain of salt.

The fact that a midlet is signed by the author (vendor) certifies two things:

  1. that the author really authored that midlet
  2. that the midlet is in original state (i.e. it hasn’t been modified by a third party)

The purpose of signing a midlet is two-fold:

  1. to gain access to security-sensible operations on the phone (such as sending an SMS or opening a TCP connection)
  2. to make sure that a (malicious) third party can’t present a different midlet as the original one

Digital signing makes use of two concepts: public-key cryptography (a.k.a. asymmetric cryptography) and digital certificate.

Signing works like this: a secure hash (also called message digest) of the midlet is computed, and this hash is encrypted with the private key of the signer. The signature is checked like this: the encrypted hash is decrypted using the public key of the signer, and is checked for equality with a computed hash of the midlet. If the two (the signed hash, and the actual computed hash) are equal it means that the midlet signature was verified successfully.

The idea is that only the owner of the private key can sign the midlet (so that the signature is verified with the corresponding public key), and that any modification to the midlet after the signing will cause the signature verification to fail.

As you see, all that is needed to check the signature is a public key. The result of the signature verification is a yes/no to whether the midlet was signed by the owner of the private key corresponding to the public key used.

But in order to be meaningful, the result should be whether the midlet was signed by a real-world entity (the midlet author/vendor, a person or company). So the public key must be associated to the identity of some author/vendor. This association between a public-key and a real-world identity is achieved using digital certificates.

A digital certificate claims that some public key belongs to some entity (a person or a company). A digital certificate contains the pair: public key, name of the entity (who owns the key). A certificate is also signed (using the same signing procedure we’ve seen above) in order to prevent the situation that a fake certificate is built by a malicious entity which claims a different identity for its key.

The midlet is signed and the midlet signature is verified against a certificate (which contains the public key needed to check the signature, and the name of that key’s owner). This certificate is also signed, and the certificate signature is verified against another certificate, which contains the public key for checking the first certificate’s signature and the name of this key’s owner. This second certificate (which signs the first certificate) is at its turn signed with another certificate. And so on, we have a chain of signatures.

This chain of signatures ends with a certificate which is not signed by any other certificate (a detail is that this original certificate is self-signed, meaning that it’s signed with its own public key, but this has the same effect as not being signed at all). The only way to be sure that this self-signed certificate is not fake is to have it in a list of trusted root certificates.

For example, your browser has a list of trusted root certificates, which contains certificates from well-known and trusted companies such as Thawte and Verisign. Any chain of certificate signatures is followed until it ends with some such trusted root certificate.

But if the final (self-signed) certificate is not found in the list of trusted certificates, then it can’t be trusted (it’s authenticity can’t be verified), so the whole chain of signatures can’t be verified.

Now let’s go back from this general signing stuff to our midlet signing. Any mobile phone comes with a list of trusted root certificates (used for verifying midlet signatures). This list contains root certificates selected by the manufacturer (e.g. Nokia) and usually also contains the root certificate of the network operator (e.g. Orange) in the situation when the mobile phone is distributed by an operator.

Let’s consider a practical example: I am a midlet author. I write a midlet, and I want to sign it, what do I have to do?
First, I need to buy a certificate from some certification authority (i.e. seller of digital certificates), such as Thawte, Verisign, GoDaddy. Because I want to use this certificate for midlet-signing, I have to be careful to select a code-signing certificate (there are also other kinds of certificates, most notably SSL certificates used to certify the identity of web sites, which can’t be used for midlet signing). So I choose to buy a code-signing certificate from Thawte for $200/year (note, the price is per year, recurring, as with a domain name).

To buy the certificate, I first generate a pair of keys, private-key and public-key. I keep the private key secret, and I send the public key to Thawte for inclusion in the certificate. Thawte checks my identity (using perhaps some photo ID that I fax them, and a phone call from them), and afterwards sends me back a certificate containing my public key and my identity (my name). Most importantly, this certificate is signed with Thawte’s root certificate (this is what for I paid the certificate’s price of $200/year).

Using this certificate I just bought, I sign my midlet, and I start distributing the signed midlet. Now some user tries to installs my midlet on his phone. The phone automatically checks the midlet signature, i.e. it follows the signature chain, starting with the midlet, my certificate, and ending at Thawte’s root certificate. If the phone has Thawte’s certificate in its list of trusted certificates, it’s all dandy and the signed midlet is installed. But if it happens that the particular phone model doesn’t contain Thawte’s certificate in its list, the signature verification fails, and the midlet isn’t installed, and the user can’t use it at all. This situation means that I paid the certification money to Thawte for nothing.

Now you may think, perhaps this example is un-reallistic, I surely may buy a certificate which is recognized by all phones? Well, no. Different phone manufacturers (and even different models from the same manufacturer) have different sets of trusted root certificates. For some phones Verisign works and Thawte doesn’t, for other phones Thawte works and Verisign doesn’t, for others neither Thawte nor Verisign works, and so on. The practical solution: buy as many certificates from different certificate vendors as you can afford (all for the same public key), and use them all when signing your midlet. When your midlet is installed on a phone, if at least one of those certificates works, the midlet signature can be verified and all is good. The downside of this method: it costs a lot of money, and it generates a lot of clut and redundant work.

What’s more: while some phome models allow the user to edit the trusted certificate list (perhaps in order for the user to add a root certificate he finds missing), many phone models do not allow it. (I can’t understant why the manufacturer would disallow the user to add new trusted certificates, I consider this a crippleware tactic. For example, Nokia S40 2nd edition allowed user access to the trusted certificate list, while the more recent S40 3rd edition doesn’t allow it anymore.)

So, let’s turn back to my case study (and publicity plug). I developed two freeware midlets (Menstral and Javia Calculator), that I distribute free of charge. Let’s say that, for the security of my users (in order to protect them from a malicious distributor who tries to impersonate my midlets), I want to sign my midlets, as to to certify that it’s really me the author, and that the midlet hasn’t been tampered with. So what do I have to do? Pay $200/year for the certificate, and have my midlets fail to install anymore on part of the phones because my certificate isn’t recognized… this is why there are so very few signed midlets.

You’d think it can’t get worse than that? why, it can: Motorola, Nokia, Siemens, Sony-Ericsson and Sun saw there is a problem and they promptly found the ’solution’: create a new certificate, and have every phone support only this new certificate, and create a signing program which will bring them more money (and have the midlet authors pay).

This new initiative is called Java Verified. The new certificate, which is the only one supported on newer Nokia phones (see Nokia 5300 at “Java verified root certificate”) is called UTI Root (Unified Testing Initiative).

And how does this Java Verified, Unified Testing Initiative works? Simply: you pay! No, really: you send your midlet to one of the Java Verified Test Providers (like CapGemini), who runs a series of tests of your midlet. For example, they check that your application provides a Help command and an Exit command, that it doesn’t hang, that it doesn’t do anything malefic (but they don’t have access to the source code), etc. They do this by running the application a few times on a real device. If they find some problems they send you back a problems report, and (after attempting to fix it) you have to pay again for one more try at the Java Verified certification. Pay, and repeat.

How much does it cost? With CapGemini, it costs 240 euro for the first submission, and 210 euro for subsequent submissions (after failing certification on the previous attempts). This price is per midlet and per targeted device. That is, if you want your signed midlet to run on multiple phone models, you have to pay once for each phone model (see a list of devices supported by Java Verified, you have to pay for each one).

So Java Verified considers that a midlet author should specify the targeted device for the midlet, the targeted device being something like Nokia 5300 or Nokia 6131. So much for the portability of JavaME applications, which says that a JavaME midlet should be able to run on a wide range of devices, from different manufacturers, with different screen sizes, etc. (And Sun, who should be the main pusher of java portability, is a member of Java Verified.)

For example, my Menstral midlet is supposed to run on any MIDP device with a color screen at least 128×128 pixels in size. I guess such a ‘targeted device’ counts as many tens of Java Verified devices.

So again, that’s why there are so very few Java Verified midlets…

Midlet-Vendor

Sunday, January 21st, 2007

A mandatory midlet attribute, which must appear in both the jad and the jar, is Midlet-Vendor; it designates, as the name suggests, the vendor (or the author) of the midlet. One problem with this attribute is that the structure of its value is not specified in the MIDP standard: it may contain any string (including whitespace). In this way, while the Midlet-Vendor attribute may still be useful for presentation to the human user, it is of limited use for authomatic processing.

Let’s consider some examples that illustrate the point:

Midlet-Vendor: Mihai Preda
Midlet-Vendor: mihai-preda

Midlet-Vendor: www.javia.org
Midlet-Vendor: myself

Midlet-Vendor: FooSoft
Midlet-Vendor: Foo Soft Inc., USA

In the first examples we see different ways of writing essentially the same vendor name, by varrying case or whitespace. While it looks the same to a human reader, certainly the vendor string is different from a computer perspective. This makes it difficult to automatically associate the different midlets with the same one vendor. There is also a second problem with such a vendor name which contains the name of the author: of course there are multiple persons with the same name (unless the author has some particularilly rare name), so it may happen that two distinct authors (with the same name) turn up being identified as the same vendor.

Let’s look toward a solution: We want the Midlet-Vendor to have a normal form, which allows to reliably compare two vendor strings in order to detect if they designate the same entity or not; and we want to eliminate the possibility that two different entities turn up using the same vendor string.

The solution that I propose is to have an URL (URI) as the content of Midlet-Vendor. In order to make it explicit that it’s an URL, the schema (e.g. http://) should be present.

Midlet-Vendor: http://javia.org/

The URL should point to a page which contains more information about the vendor; it could point to a company’s home page, to the blog of the author, etc.

One objection to this solution could be that the Midlet-Vendor is also intended for presentation to the human user (of the mobile phone), and the company URL is not as clear to a human as the company’s name. While I don’t necesarilly agree with this argument, a solution would be to have the Midlet-Vendor contain a free string (the company name, intended for user presentation) and an URL, intended for equality-comparison between different Midlet-Vendors. Examples of good Midlet-Vendor strings:

Midlet-Vendor: Mihai Preda (http://javia.org/)
Midlet-Vendor: Foo Soft Inc. (http://www.foo-soft.com/)
Midlet-Vendor: http://google.com/

The important point is this: the Midlet-Vendor should always contain an URL (eventually enclosed in brackets), and only the URL should be used for equality-comparison between different Midlet-Vendor strings.

But according to the MIDP standard, the full Midlet-Vendor string must be compared for vendor-equality — so in practice I would suggest to use only an URL as the content of the Midlet-Vendor.

Menstral’s new feature: SMS transfer

Thursday, December 7th, 2006

Menstral is a menstrual calendar (also called called cycle or ovulation calendar) application I wrote one year ago.

Menstral 1.9.0, released today, adds an interesting new feature that I’ve called SMS Transfer: it allows you to send your calendar data, through SMS, from one Menstral instance to another Menstral instance running on a different phone.

This is useful for the users who change/upgrade their mobiles, as they expect to be able to continue using the applications from their old mobile on the new one (this expectance includes the continuity of the persistent RMS data).

I wonder what other mobile applications out there are using the SMS Transfer. I’d suspect this technique will become more popular as the developers realize that they have to catter for their users’ habit of periodically switching mobiles.

And one more prediction from my foreseeing bag:
The young(ish) mobile users will grow out of the pictures/ringtones through MMS thing (which never really took off anyway), as soon as they’ll discover they can now send menstrual calendars through SMS.. wow!

(On the same funny line, a surprising observation is that a significant part (perhaps more than a half) of Menstral’s users are Men!)

JAD is BAD

Saturday, December 2nd, 2006

JAD is an acronym for Java Application Descriptor. JAR comes from Java Archive.
In the MIDP world, the JAD is a small text file (with the extension .jad) which contains a few lines of information about a Midlet application.

An example JAD file:

MIDlet-1: Menstral, /M.gif, M
MIDlet-Name: Menstral
MIDlet-Vendor: Mihai Preda
MIDlet-Version: 1.8.11
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-Jar-URL: http://menstral.net/Menstral.jar
MIDlet-Jar-Size: 31105

Noteworthy inside the JAD are the MIDlet-Jar-URL line, which indicates the location of the JAR, and the MicroEdition-Configuration and MicroEdition-Profile lines, which represent the required versions of the CLDC and MIDP that the device must support in order to be able to run the application.

One way to install applications is: the phone downloads the JAD, checks whether the required versions of CLDC and MIDP are satisfied, and if the answer is positive it proceeds to download the JAR file containing the application.

Another way is to directly download the JAR. This works because every JAR contains inside a special file, the Manifest, which contains mostly the same information as the JAD. That is, the phone can do without the JAD because it can get the same information from the Manifest found in the JAR.

So, if the JAD is duplicated inside the JAR (in the Manifest), and the whole download/installation can proceed very well without the JAD, what is the reason for the JAD’s existence?

Well, the idea is that the JAD is small, but the JAR is not so small. If your phone can’t run the application (because it doesn’t satisfy the required conditions specified in the JAD), it’s better to just download the JAD to find it out (and skip the bigger JAR download in this case).

This is the only gain of using the JAD/JAR pair compared to using only the JAR: you don’t have to download the (big) JAR in the situation when your phone can’t run the application.

But here comes the surprising affirmation: the JAD is actually a bad thing, and the fact that this whole JAD concept got into the MIDP standard is a flaw, and we, as midlet developers, should favor the “JAR-only” distribution, thus driving the JAD to practical obsolescence even if it is in the standard.

Here is why the JAD is BAD:

The JAD is not needed

1. The situation when the JAD saves bandwidth by avoiding the JAR download is infrequent.

Most users download midlets that run on their device much more frequently then they download midlets that don’t run on their device. This is because at the point when they decide to download a midlet, they have strong reasons to suppose that it will run on their phone. One factor is that the web server which offers the download can detect the phone’s capabilities (e.g. by using the User-Agent info sent by the phone) and can only offer for download midlets which can run on the particular device. Another factor is that the midlets’ web page contains textual information about their requirements, such as “This midlet runs on any MIDP 1.0 mobile phone”, or “this midlet runs only on Nokia, MIDP 2.0 phones” etc, that the users can evaluate before initiating the download.

2. The JAD benefit, infrequent as it might be, is small.

Even in the (rare) situation when the JAD saves the user from downloading the JAR, it only saves a few tens of Kilobytes of bandwidth, which is not likely to make a big difference to the user. It’s not like the JAD-avoided JAR download is a must-have lifesaver feature that users simply can’t do without — quite the opposite.

3. The JAD’s benefit can be harnessed without using the JAD.

Here it gets interesting: the JAD concept isn’t needed in order to get the bandwidth save mentioned before. The same bandwidth saving can be obtained without the JAD.
This is how:
- have the archiver which creates the JAR archive always position the Manifest file at the beginning of the archive.
- have the mobile’s downloader incrementally extract the Manifest while the JAR is downloading. As soon as the Manifest has been extracted, but before the whole JAR was downloaded, inspect the Manifest to see if the device can run the application. If it can’t, stop the download without transferring the rest of the JAR, thus saving bandwidth.

The MIDP JSR, instead of the over-designed JAD contraption, could have simply used two non-normative guidelines: the java archiver (jar) should place the Manifest at the beginning of the archive, and the mobile’s software should inspect the Manifest as soon as it becomes available during the download. But I guess the standard-makers were too busy to consider the simple solution.

The JAD comes with a cost

So, we’ve seen it could have been just as good without the JAD, but one might argue: one the other hand, it’s not like having this JAD thing hurts either. Well, it does hurt:

1. The users

There are two main ways to install midlets: over the air (downloading them directly on the device), and by copying the JAR from your desktop to the phone’s filesystem using a data connection (infrared, bluetooth, usb, etc). The second way of installing can’t use the JAD, but must use the JAR. So the midlet download sites can’t offer just the JAD to their users, they must offer the JAR too (in order to support the filesystem-istall).

The user who wants to download a midlet is presented with the choice: here is the application you want, Foo.jad and Foo.jar. The user stops and thinks: which one should I choose? or maybe I have to use both? or perhaps I’ll try one and then the other, and see which one works? and what’s that jad thing anyway? etc.

I just think of all the users that installed on their phone’s filesystem only the JAD, and afterwards wandered why it doesn’t work. Even myself, before being a midlet developer I was a midlet user, and I kept installing on the phone’s filesystem both the JAD and the JAR, because I didn’t understant their roles (of course, on the phone’s filesystem the JAD was useless and ignored). It took me a few midlet installs and google searches until I realized that the JAR is enough and that I don’t need to bother with the JAD.

The general principle is: don’t make the users choose/think, and they won’t get confused.

2. The developers

The JAD adds significant complexity, even if this is not obvious at the first sight. For example, think of the conflict resolution rules for the situation when the same key has different values in the JAD and in the Manifest. Did you consider the signed midlets?

Or think about which keys should be placed only in the JAD, which ones should be placed only in the Manifest, and which ones should be placed in both the JAD and the Manifest. And the complexity applies also to the device developers who have to implement the standard.

Conclusion

I suggest that midlet distributors offer only the JAR (and drop the JAD), as this will reduce the confusion of the users.

The guidelines concerning the placement of the Manifest at the beginning of the JAR, and the early inspection of the Manifest during download should also gradually come into use.

Mobile Java

Tuesday, November 28th, 2006

In the previous post I described what I call “Assembly Java”. The name itself, Assembly Java, is paradoxical (oxymoronic) through the opposition between a high-level programming language (Java) and a low-level programming style (’assembly language’).

The previous post was intended, I guess, as a (subtle) critique of Java used as a low-level programming language.

In the constrained mobile (MIDP) environment, the Java language becomes deprived (through the low-level programming style) of its advanced features, such as classes, virtual dispatch, polymorphism, packages, reflections, and, to some degree, garbage collection. Java turns into a C-like low level language, while still missing some of the C features that would have been useful in the restricted environment, such as: data structs, stack-allocated instances (’auto’ variables, object instances that aren’t allocated on the heap), arrays of structs (with the structs stored inside the array, not with pointers stored in the array), inlined functions, preprocessor (used for conditional compilation and macro expansion), enums (useful for the ’switch-dispatch’ pattern, among other things), first-class functions (’function pointers’), etc.

But don’t get my critique too harsh: I’m an enthusiast mobile Java developer myself, and I would recommend Java as the first choice (by far) for mobile application development.

There is also the time aspect: due to the quick evolution of the hardware, the mobile environment is becoming less and less constrained, and thus mobile Java programming is gradually getting closer to the standard Java programming, employing less low-level optimizations and more high-level design. Also the mobile VM (java virtual machine) should be expected to become smarter in time and, why not, perhaps the java compiler (javac) might employ some compile-time optimizations (such as method inlining, and a bunch of expression and loop optimizations) as well.

In the meanwhile, a smart obfuscator such as Proguard can help with the size-reduction of the compiled classes (through automatic class and method renaming, package renaming and elimination, class-merging, method inlining), thus allowing you to keep your design/code simple, clear and clean, while still taking advantage of these optimizations. (note: class-merging is still experimental in proguard, and method inlining is planned for the future).

For the developer, the first concern should be to (quickly) implement the application and get it to work correctly, and only afterwards does the performance (and optimizations) come into discussion. This is simply because the performance of an unfinished or failed project is of little importance.

Getting the application done is no easy task. You should take advantage of clean design, simple code, clear and small interfaces, hidden (private) implementations, because all these help you to develop your application, to modify and adapt it, and to reuse your code.

You should strieve to achive beautiful code, kind of an art-work. A measure for this is to imagine that your code is open-source, and all your friends look at it and discuss it. If you’d still be proud of your code were it public, it’s a good sign.

The so-called guidelines from my previous post are rather bad advice, and were intended for your entertainment (note that #0-#10 is in fact 11 items, not 10 as stated in the post). By negating (complementing?) them you might get some sound design advice.

Let’s try the negation trick:

#0. Don’t merge classes.

You should not merge un-related functionality together in a single class. You should keep the class design clear and neat because it makes the code easier to understand, to modify, and to reuse between projects. As classes do incur some space overhead, you should avoid the extreme of class inflation, the situation where you have a large number of very small classes (classes with just one or two methods inside). Perhaps a reasonable number of classes might be somewhere between 4 and 20 classes, depending on project size and design complexity.

Proguard the obfuscator offers an experimental merge-class feature. This is another reason to keep your design/code clean, with nice classes, and you can always get the merged-class benefit at the obfuscation step if you want it, with no negative impact on your class design.

#1. Don’t merge methods.

The space overhead of a function declaration is so small, that you shouldn’t worry about it. Do split big methods if it increases the clarity of the code. Strive for having each method do just one thing. Try to have methods with small and clear signatures (small number of parameters) and clear semantic (’what does this method do?’).

#2. Switch or polymorphic dispatch?

Using the switch() instead of the polymorphic dispatch is generally considered bad OOP practice. You may nevertheless want to do it sometimes to avoid having a large number of small classes. Ponder well when choosing between the two.

#3. Instantiation vs. reuse

While object instantiation economy is not bad, don’t sacrifice too much of your design quality for the sake of it, because at the same time object instantiation / garbage collection is not prohibitively expensive when done with measure. The places where you should keep an eye on object instantiation is inside tight loops (e.g. inside a for loop, it may be a bad idea to repeatedly instantiate / garbage collect a temporary object — you may want to instantiate it just once outside the loop, and reuse it during the loop).

I’ll stop here, saving you the remaining ‘guidelines’.

The 10 principles of Assembly Java

Monday, November 27th, 2006

Assembly Java is a particularly economical and efficient style of usage of the Java language. These are the principles of Assembly Java:

#0: Define as few classes as possible. Ideally, use a single class.

How: Pack as much as possible in each class. Merge conceptually-unrelated classes together, when possible.
Why: Every class incurs a space-overhead (of about 200 bytes) in the final jar. Having everything in one class also improves the class-locality (as all the methods/fields you use are likely to be from the same class).
Limit: The minimum number of classes you may use is given by the number of classes that you have to extend, as you have to define a new class for each inheritance.

#1: Define as few methods as possible.

How: pack as much of sequential logic as you can in a single big method. Don’t split methods solely for clarity’s sake; merge them.
Why: Performance gain by avoiding method call overhead. Space gain by avoiding the overhead of the method declaration.
Limit: You need a separate method for each method you overload, in particular for each abstract method you implement.

#2: Avoid polymorphism; use switch() instead.

How: Rather than declaring a base interface or abstract class, and extend it in order to polymorphically customize behavior,
use a single concrete class with switch statements for all variable behavior. Declare integer constants identifying the behavior cases.
Why: Size gain by reducing the number of classes (#0 above) (abstract classes and interfaces are as bad as any other class). Performance gain by avoiding the virtual dispatch.

Bad Assembly Java:


abstract class Animal {
  abstract String saySomething();
}

class Dog extends Animal {
  String saySomething() { return "how how"; }
}

class Cat extends Animal {
  String saySomething() { return "meow"; }
}

Good Assembly Java:


class Animal {
  static final int DOG=1, CAT=2;
  String saySomething(int kind) {
    switch (kind) {
      case DOG: return "how how";
      case CAT: return "meow";
      default: return null;
   }
}

#3: Avoid object instantiation (object creation).

How:
Reuse the same object time and again. All classes should have a init() or reset() or reinit() method (instead of a constructor) which would allow the re-use of the old object.
Don’t return objects from methods (because this likely requires the creation of the object to be returned), instead have the method take an out object parameter, which is passed in by the caller (who can reuse it) and is filled by the method with the result value.
Why: Performance gain by avoiding the object allocation overhead, and by reducing the garbage-collection overhead. Memory footprint reduction by decreasing the number of allocations.

#4: Don’t use packages. Put everything in the root package.

Why:
The package names incur some space overhead in the compiled classes.
Due to class-merging (#0), the package concept is anyway already irrelevant.
Having everything in a single package allows global access to package-visible methods and fields, thus enabling technique #5a below.

#5: Avoid method calls.

Why: Performance gain by avoiding the method call overhead. Also see #1, Define as few methods as possible.

#5a: Avoid accessor methods (getters, setters). Access directly the data members.

How: having everything in a single package (#4) allows access to all the members except the private ones. I.e., you don’t have to make a data member public
just because you want to access it, package-visibility is enough.

#5b: Inline small methods.

Why: avoids call overhead and reduces the number of methods.
How: use a preprocessor and preprocessor macros for the inlining. As the Java language doesn’t have a default preprocessor, you have the liberty to use any preprocessor you like. For example you may use CPP (’C Pre Processor’) from GCC, but there are plenty of other choices.
Note: don’t trust the compiler or the virtual machine to inline your small methods (#7).

#6: Don’t use String. Use char array instead.

How: have a large char array, and use a pair of indices (begin, end) inside the array to delimitate your string.
Why:
Reduces the number of object creations and method calls. A char array (with a pair of indices) allows you to extract substrings without object creation,
and to iterate over the characters without the overhead of a method call for each character (String.getAt()).
Also enables a method to return a string without requiring object instantiation (by passing the char array as an out parameter to the method).

#7: Don’t trust the compiler or VM with the optimizations.

Why: the only optimizations you can rely on are the ones that you explicitly code yourself. Conservatively consider the compiler and the VM as dummy as possible.
Bad:


doSomething(2*n, 2*n+1);

Good:


int doubleN = n << 1;
doSomething(doubleN, doubleN + 1);

#8: Avoid array of objects, use multiple elementary arrays instead.

This is best described by an example. Let’s say you need an array of points, where a point is a pair of two integer coordinates (x, y).
Instead of the first-shot solution:


static final int MAX_POINTS = 100;
class Point {
  int x, y;
}
Point myPoints[] = new Point[MAX_POINTS];
{
  for (int i = 0; i < MAX_POINTS; ++i) {
    myPoints[i] = new Point();
  }
}

Use the much-improved solution:


int Xs[] = new int[MAX_POINTS];
int Ys[] = new int[MAX_POINTS];

Why: you gain one less class, and a lot of memory footprint from avoiding the many object instantiations.

#9: Use the all-static singleton.

Every time you have a class that will have a single instance, you should take the opportunity to use the singleton pattern.
The preferred way of implementing the singleton is to declare all the fields (methods and data) static. This avoids the need to allocate an instance of the singleton class (saves memory), and allows for the class-merging of the all-static singleton with any other (non-singleton) class, thus saving one more class definition (#0).

#10: Avoid exceptions.

Why: The try/catch block incurs a space overhead (in the compiled class). There is also a performance penalty when an exception is thrown/caught.
How: Don’t throw. Don’t catch. Don’t define new exception classes (#0), use the standard Error or RuntimeException instead (these are unchecked exceptions, so you don’t have to catch them) if you really have to throw at times.

Conclusion

The name Assembly Java makes reference to Assembly Language, which too is renowned for its outstanding performance and ressource efficency.

So these are the 10 principles of Assembly Java (#0 - #10 above), use them well.

Update 2006-11-30: there is a follow-up to this article, called ‘Mobile Java’, that you might want to read as well.

Good old factorial

Saturday, November 4th, 2006

A simple routine for computing the factorial in java, with good speed and low footprint.


static final double factorial(int n) {
    if (n < 0) {
        return Double.NaN;
    }
    if (n > 170) {
        return Double.POSITIVE_INFINITY;
    }
    double x = n, tail = x;
    switch (n & 7) {
    case 7: tail *= --x;
    case 6: tail *= --x;
    case 5: tail *= --x;
    case 4: tail *= --x;
    case 3: tail *= --x;
    case 2: tail *= --x;
    case 1: return FACT[n >> 3] * tail;
    case 0: return FACT[n >> 3];
    }
    return 0;//not reached
}

private static final double FACT[] = {
    1.0,
    40320.0,
    2.0922789888E13,
    6.204484017332394E23,
    2.631308369336935E35,
    8.159152832478977E47,
    1.2413915592536073E61,
    7.109985878048635E74,
    1.2688693218588417E89,
    6.1234458376886085E103,
    7.156945704626381E118,
    1.8548264225739844E134,
    9.916779348709496E149,
    1.0299016745145628E166,
    1.974506857221074E182,
    6.689502913449127E198,
    3.856204823625804E215,
    3.659042881952549E232,
    5.5502938327393044E249,
    1.3113358856834524E267,
    4.7147236359920616E284,
    2.5260757449731984E302,
};

Signed Midlets

Sunday, August 20th, 2006

Since MIDP 2.0, a midlet can be unsigned or signed (in MIDP 1.0 all midlets were unsigned). A midlet which is signed can get easier access to sensible operations. For example, let’s suppose that a midlet wants to access the network (http). If it’s unsigned, the user is asked for confirmation each time the midlet does the operation. While if it’s signed, the user can choose to allow the midlet access without further confirmation. So if you write, for example, a multi-player game, you should perhaps sign it because otherwise the user will be bothered with access confirmation questions all the time.

Afterwards you sign the midlet using your private key, and you distribute the signed midlet together with your public key and the certificate. When the midlet is installed on the device, the signature is checked. This insures that the midlet was not modified since you signed it (integrity). Afterwards, the certificate which accompanies your public key is checked, by having it’s signature verified. As you remember, the certificate was signed by the CA. In order to verify this signature, the device needs the public key of the CA. The public key of the CA should normally be already installed on the device, in a so-called “Root Certificate”.

The idea is that there are a few well-known CAs, which are generally trusted by everybody; and you’d expect that the public keys of these well-known CA to be on installed on the device as Root Certificates. For example, well-known CA are Verisign and Thawte.

So all you need to do, in order to be able to sign your midlets, is to obtain a certificate from a CA. The problem is that it’s costly for a freeware developer: a certificate costs 200$/year from Thawte, and 400$/year from Verisign. Afterwards comes the second problem: not every phone has both Thawte or Verisign installed as root certificates. So you may, for example, buy a (costly) certificate from Verisign, only to find out that it doesn’t work on your target device. The recommended practice is to buy a few (2-3) certificates from different CAs, in order to improve phone root-certificate coverage.

An alternative to Thawte and Verisign is JavaVerified, a commercial initiative which verifies that your midlet is well-behaved and signs it afterwards with their (JavaVerified) certificate. This way you don’t need to buy your own certificate, and what’s more the JavaVerified root certificate is generally very well supported on phones. The downside is that with JavaVerified you have to pay many hundred $s (more likely in the thousands) for every midlet that you want certified, so this ends up being significantly costlier than the first solution. JavaVerified works by delegating the work (midlet verification) to four partner companies, which set their own prices; you are allowed to choose one of the four companies for verifying your midlet.

One of the JavaVerified partners is CapGemini. As I worked for a short while at CapGemini, I can tell you that this is the worst company I’ve met. Having my midlet ‘certified’ by CapGemini is a joke to me. So for now, I’d qualify JavaVerified as the place where you can throw your money away when you have no better use for them.

And on a positive note, Symbian has a similar program called Symbian Signed. What’s great, is that Symbian Signed is offering free certification for freeware applications. This is really a very nice thing, and it’s a great incentive for the small developers to write applications for Symbian (instead of JavaME).

My impression concerning the security model of JavaME / MIDP 2.0 is that they were less concerned with the security and comfort of the users, and more concerned with making sure that everybody (manufacturers, operators, JavaVerified etc) gets its share of profit from the certification business. Some operators (Orange, Cingular) even go as far as to completely disallowing the installation of unsigned midlets on their phones; I can only see this as an expression of their greed in the detriment of their users.

Digital Signature

Sunday, August 20th, 2006

I’ll describe here in short how signing works:
A key is a pair of a private key and a public key. These two key have the property that what is encrypted with one can be decrypted with the other. So if you encrypt something using the private key, it can be decrypted using the public key, and vice-versa. You keep the private key secret, so that only you can use it. When you sign a document, a message digest (MD) of the document is computed. A MD is a secure hash of the document; it has the property that each document has it’s own MD. You can’t find a different document which has the same MD as a given document. Because of this, the MD can be seen as a characteristic of the document. If you make any change to the document, its MD changes. So you compute the MD of the document you want to sign, and afterwards you encrypt the MD using your private key. This encrypted MD represents your signature of the document. The signature assures two things: that you indeed signed the document (non-repudiation), and that the document wasn’t changed from the form that you signed (integrity). Now let’s see how the signature is verified: another person receives the document together with the signature (the encrypted MD), and wants to check if the document was signed by you. He decrypts the MD using your public key, and also computes a new MD of the document. If these two MDs are the same (the computed one, and the one decrypted from the signature using your public key), it means that indeed you signed the document. If they’re not equal, it means that either the document was signed with a different key (i.e., it wasn’t signed by you), or that the document was modified since you signed it.

There is also a different aspect: how is the person who verifies the signature sure that the public key he thinks is yours really is yours? Non-repudiation means that once you signed a document, you can’t deny that you signed it. You may try to say something like: that public key is not mine; so it’s not me who signed the document; it’s not my signature. In order to make such denial impossible, the person verifying the signature wants to be sure that the public key really is yours, and that you can’t deny this fact. This is achieved by having your public key certified by a Certification Authority (CA). A CA is an organization which verifies (at your request) your identity, and emits a certificate declaring that the given public key is yours. This certificate is signed by the CA. So this certificate, signed by a CA, is the mechanism which makes the link between a public key and a real-world identity.

It order to be able to sign, you need a key (a pair of a private key and public key). You may easily generate any number of keys yourself, using a program like OpenSSL. Afterwards, you need to associate the public key with your identity (your company name, for example). This is done by obtaining a certificate from a Certification Authority (CA). The CA verifies your identity (by calling you on the phone, or by having you fax them some official documents declaring your identity), and afterwards gives you a certificate, which says that the given public key belongs to you.

Popular mobile phones

Sunday, August 20th, 2006

These are some popular phones that people are still using for running JavaME applications:

Nokia 6600 176×208, MIDP 2.0
Nokia 6230 128×128, MIDP 2.0
Nokia 3510i 96×65, MIDP 1.0
Nokia 3200 128×128, MIDP 1.0
Nokia 3100 128×128, MIDP 1.0
SE K700i 176×220, MIDP 2.0

JavaME opensource; MIDP emulators

Saturday, August 19th, 2006

MIDP 2.1 was released on 20 June 2006.
It only brings minor differences with respect to MIDP 2.0.

MIDP 3.0 is expected to be released toward the end of 2006.
The Reference Implementation (of MIDP 3.0) will be released as Open Source under the Motorola Extensible License.

Sun recently announced that it plans to open source JavaME before the end of 2006; this would mean to open source the WTK and perhaps the MIDP 2.x Reference Implementation. Sun has yet to decide what license to use.

I recently looked into emulators capable of running JavaME applications as an applet in browser (JavaSE). Such an emulator is useful for presenting MIDlets in the browser, so that the user is able to try the application before installing it on the phone.
Right now it is usual to put screenshots (pictures) of MIDlets on the web page, but having a running screenshot allowing to try the application is much more powerful.

The emulators I found are: ME4SE and Microemulator.
ME4SE is licensed under GPL. It isn’t developed anymore. It implements MIDP 1.0, and partially MIDP 2.0. Also some functionality (like phone skins) isn’t released under GPL, but only available under a commercial license.
Microemulator is under active development but it seems to be, right now, less mature than ME4SE. Microemulator is licensed under LGPL.

In short, while both projects are interesting, none is very useful now; and it seems that only the Microemulator is progressing. Yet what they potentially offer, the possibility to run MIDlet in the browser, is very useful indeed.

What is interesting to see is whether the annonced release as open source of the MIDP 2.0 and MIDP 3.0 RIs (reference implementations) will allow to easily transform them in MIDP emulators over JavaSE. We only have to wait about 4 moths (until the end of 2006) to see it.

Typing URLs on a phone keypad

Tuesday, June 20th, 2006

Typing text on a phone’s “12key” keypad has a different metric than typing on a normal computer keyboard. Typing on a phone comes in two flavors:

  • using predictive input (T9), where you only hit each key corresponding to a letter once, and the word is disambiguated based on a dictionary
  • using repeated key presses to select the individual letter from the group of 3 (or more) letters associated to a key

When typing URLs a dictionary is not very helpful, because usually the URLs aren’t composed of dictionary words. This means we can’t use T9 for URLs, so we’re left with the “repeated presses” typing method.

The slowest typing situation happens when one has to type successive letters that are located on the same key. Example: typing “abac” is slow. All these letters (a, b, c) are located on the same key “2abc”. You have to make a small pause after each letter to indicate the advancing to the next letter. Were the successive letters located on different keys, no such pause would be necessary.

I’ve written a small script which computes the cost of typing a given text on a phone keypad. You enter any text and it shows a number, the cost. The smaller this number, the easier/faster to type is the text:

http://frumos.com/cost.html

(by the way, this is the first Javascript code I’ve ever written)

For example, here are some text fragments, with their respective costs (smaller cost is better):

javia.org 20
javia.eu 17
com 9
net 5
org 7
mobi 11