Friday, December 19, 2008

Every Byte Counts

Well, it has been a while since I've posted anything. I've been really, really busy trying to figure out how to save every last byte that I can over the network for mobile applications. When all you have is an EDGE network, you really can't spare anything.

Here are some of my findings:

  • Don't use SOAP. If you're going to use a standardized communication method, prefer REST to SOAP. Why? Because even if SOAP offers a lot of information in its message envelope that is very useful for implementing integrity, security, transactions and not to mention making it easy to orchestrate via an enterprise bus, it also happens to be much larger. Expressing a resource in REST will save you a lot of bytes.
  • Another reason, is that REST isn't bound to XML like SOAP is. JSON is so much shorter than XML. Furthermore, most Java ME platforms have zero support for XML. To be fair, Java ME has zero support for JSON too. Support for both is readily available using 3rd party libraries however, again, the JSON library is much smaller than the XML one. Using JSON, not only do we get something that is more compact than XML, we don't lose any of the flexibility. You can express any XML construct in JSON, and just like XML, you can extend your JSON documents in the future with elements that can be ignored and parsed over by older clients.
  • Gzip encoding is your friend. Mostly all HTTP servers support it, just add the "accept-encoding" header to your request. Needles to say, Java ME doesn't support gzip but once again 3rd party libraries are readily available
  • Keep alive connections. HTTP 1.1 supports keep alive connections out of the box. What that means is that you can send one http request, read the response and instead of closing the socket connection, you can re-use it to send and receive additional requests and responses. This is also unsupported from Java ME, and no, to my knowledge, there are no 3rd party libraries available that support this. Fortunately, HTTP is a really simple protocol, you will need to forgo the use of the HttpConnection class and use a raw socket via the SocketConnection class. You just need to send well formed HTTP 1.1 requests to the server and you should be able to read responses just fine. This saves you the setup and tear down times associated with a full TCP socket connection every time you need to send a request. Please note however that you will need to support, at the very least, the "chunked" encoding since HTTP 1.1 compliant servers are free to use this encoding whenever they so choose.
However, most disappointingly, probably one of the best tool you can use to save bytes over the network is not available. I am talking about HTTP pipelining. HTTP pipelining as specified in version 1.1 of the protocol allows you to send many requests to the server on the same socket before you start reading any of the responses. Unfortunately, my server of choice, Glassfish, has no support for it. If Glassfish has no support, most certainly no Java EE container does either. The HTTP parser found in Glassfish is none other than Tomcat's Catalina engine. Since Catalina is used verbatim in almost every Java EE container out there, then that's it.

Most unfortunately, the Grizzly project team members have decided that HTTP pipelining is not a mandatory or important feature of HTTP 1.1 since the browsers don't enable it by default. Grizzly is the HTTP server used inside Glassfish and fronts the Catalina engine in Glassfish instead of Tomcat's own Coyote server. I disagree with this conclusion. I think this W3C document states that pipelining is indeed mandatory.

I would love to hear from someone with Jetty experience here if this feature is supported or not. I use many Java EE 5 features that would make the transition to Jetty impossible but the Apache Geronimo project does feature a certified Java EE 5 server built around Jetty.

Finally, if anyone would like to suggest more ways to save bytes in a portable manner, please feel free to comment.

Friday, October 10, 2008

No More Heroes 2

I'm so happy that the first game did well enough to warrant a sequel. If you don't own a Wii, there's never been a better excuse to get one.

Trailer for No More Heroes: Desperate Struggle.

Wednesday, September 24, 2008

First Android Device Fails to Impress

T-Mobile in cooperation with Google yesterday announced the G1. I watched the video of the entire press conference. I think Google is not adapting to this new market instead relying on doing business the same way it does on the web. This may have proved successful for their web business but I don't think it will work out very well for the mobile market. Things that just don't work include:
  • No desktop application for syncing. Google is positioning everything to sync from the cloud, gmail, google calendar etc. Yeah, this is just going to be such a joy for organizing your music and other media files on your device.
  • No iTunes support. The largest music retailer in the world will not function with Android.
  • Sim locked to T-Mobile. 2 year contract with a retail price tag of $175. OK, so the device costs a lot more than $175 hence the contract, so why can't we just buy the full version? So much for this open thing.
  • The device is bulky, favoring a full pull out keyboard instead of a touch keyboard similar to the iPhone. I think this is more of a problem with HTC than the Android platform itself. However, now that I think about it, I haven't seen a touch keyboard on this platform period. The emulators don't have it.
  • Limited Bluetooth support and APIs. Google has pledge that future versions of the software will expand on these services.
  • Google Android Market is a good thing but are these devices actually upgradable? Can we upgrade from Android 1.0 to future Android releases?
  • For the relatively small price difference, that 8 GB flash drive found in the iPhone is looking very attractive. Honestly, dump the SD cards already.
  • Tooling support is still sub par. No visual designer is available but the latest Eclipse plugin has visual preview so this may be in the works. However, DroidDraw is available and is pretty good.
Not all is bad however, the strength of the platform is still Java SE. Android is a subset of the full Java SE 5. You can see the number of packages for Android here and for Java SE 5 here. It may be a subset of Java SE 5 but it's still huge compared to any other mobile platform out there. The other thing is that the Android compiler works on Java byte code. So any library written for the Java SE 5 platform, and yes, there are quite a few of them out there, can be potentially used on this platform.

Friday, September 5, 2008

Recipient Address Rejected with PostFix and JavaMail

Really not sure anymore what I wanted to talk about this exactly. I had this problem and the only thing I can recommend if you do have this issue is that the bug is usually in the order of the parameters you pass to JavaMail and not in your PostFix configuration proper.

JavaMail has way too many parameters that are just strings, with methods that take a lot of strings, it becomes way too easy to mix up one string parameter with another.

Folders in a Database

If you're using folders and storing them in a database, the conventional approach is to use recursion for things like folder validation, moves and membership.

Using recursion with a database like this is usually pretty bad performance wise, consider using a token instead. A token could be, for example, a folder id string field that keeps the path of the folder using the identifiers of all its parents.

So, if you had folders "a/b/c", the folder id string for the "c" object could be "/100/101/" representing the path to this folder.

In application code, you should obviously never manipulate this string directly, the string should be completely private to your inner most classes that represent your data model.

Using this technique however, it becomes very simple to answer some very basic questions like:
  • Can I drop this folder into this other folder? Simple, just check if the string starts with the same path or is equal. So "c" can be dropped into "a" or "b", but "a" cannot be dropped in "a" or "b" because the path for "c" contains "a".
  • How many items are contained in this folder? Just check how many items have a matching string.
  • Makes it easy to find siblings, all the items found in the same folder have the same folder id/path.
If you do keep using recursion, make sure your code is secure at least, don't allow for an infinite number of recursions.

Thursday, September 4, 2008

Push vs. Poll

It seems pretty obvious at first but this is no simple matter. For years, I have been in the poll camp. The idea was that if you had long running processes that would poll for updates every 20 to 60 minutes, the cost of setting up, performing requests and tearing down a connection would be less than the cost of maintaining a connection on the server.

Well, there are several problems with this scenario. The first one being that under such conditions, the total number of bytes needed to perform the requests on the server usually ends up being a higher number than the total bytes needed to produce responses to indicate that no new data is available since the last poll. The second is that it is much harder to limit incoming requests to the capacity of your servers. Namely, given n number of client processes out in the field, entropy sets in and will cause your clients to poll at different times. However, as the number of client processes gets bigger and bigger, the number of simultaneous polls that hit the server at the same time grows at the same rate. Using push, we can feed updates to clients at a rate that the server can handle. Since the server is responsible for contacting the clients, it can do so at its own pace completely sidestepping the “Thundering Herd” problem. Third is that not all bytes are of equal cost. In this ever heterogeneous computing landscape, e.g., the cost of a byte on a high speed DSL line isn’t the same than the cost of a byte on a cellular edge network. In the scenario above, sending requests that have empty responses should be a no cost operation on a domestic high speed link but this doesn’t hold true for a user on the cellular network. Fourth, given an update that needs to be pushed, that single piece of information is completely independent of any updates that came before it and will come after it, meaning that it is easy to distribute this work to a farm. For example, we can imagine that for a poll, we would need to query the database for each and every poll. For a push, we would push the result of running a single query to multiple clients. The fourth argument is much more domain specific since your data might not allow for this at all but it’s still perfectly possible on some data sets. Fifth, web applications are not kiosks, they can't be polling only once every hour. However, even for kiosks, push is still superior since it allows for instant monitoring of every client in the field.

The term coined for server side push is comet, or reverse Ajax, and you use this to get to your clients, be it a web application or not, to achieve a server side push. However, the problem is that too often the solutions ends up looking something like this:

but this is not the most optimal solution. First, it does not get rid of the extra request traffic that we are trying to avoid. This is not really server side push but more of a constant poll where the response timeout is extremely high. With comet, the idea is to get to a point where you're shaping your traffic like this:

Not only does this get rid of our unwanted traffic, it truly does provide a scalable way for the server to publish change sets to clients without having to exert itself.

Now the bad news, achieving comet isn't just about behaving in a certain way at the network level. Reaching this level of sophistication means that the server is maintaining work queues of the data that it needs to send to clients. This isn't too bad but remember that not every client will be synchronized to the latest updates when sending out new updates. Your clients will still need to get to the synchronized state using regular requests before they can get updates via comet.

Finally, I would like to mention that there are several tools and kits and what not to add comet support to your application, you don't need to do it yourself. However, I have found that Grizzly, the http web server that ships by default in Glassfish, to be an excellent choice for all my comet needs. Grizzly is really an impressive piece of code, using non-blocking I/O everywhere with a minimal amount of threads to achieve maximum throughput. You'll still need to handle things like dropped connections and other exceptional conditions but the hard part of getting a scalable comet implementation going in the first place will be done at least. Furthermore the plan for Grizzly 2 calls for enhancing the server with the new asynchronous I/O facilities being introduced in Java SE 7, which should make this already impressive beast scale to new heights.

Sunday, August 17, 2008

NetBeans Exception Reporting

I've talked before about how crash reporting hasn't yet entered the mainstream of available services from open source hosting sites. GNU Savannah, Sourceforge, Google Code, none of them provide crash reporting to their customers. If your program crashes in the field, you either need your user to report a bug manually or you need to implement or reuse a crash reporting system, but more importantly, you also need to host your own crash reporting service.

I've talked before on how this is really a shame especially considering that Google produces breakpad, certainly good enough for the C and C++ community to start improving the quality of their software thanks to good crash reporting and some projects definitely are, albeit, again, using their own servers.

To this day, Microsoft is the only company that is hosting an error reporting service that it makes available to all developers in the form of Windows Error Reporting. Kudos to Microsoft for this effort.

I've been very enthusiastic about my jump from C++ to the Java platform, or to a much lesser extent the .Net (Compact) platform. The reasons for this aren't related to language features, C++ armed with smart pointers and modern libraries and idioms can easily compete with the Java 5 language and C#.

No, the reason is how much richness is kept in the compiled binary format representation of these platforms. Of course, the massive advantage of Java over, well, pretty much everything else, in the number of high quality libraries that are available certainly helps too. The point being if you've had to deal with post-mortem debugging before, the rich and high quality stack traces you can get from a Java exception versus the information you get from a minidump file is night and day. You can't get this from a C or C++ program even if you do all your symbol generation correctly because a lot of good and necessary information is optimized away. While with the other two, the non optimized version is still available on disk since it's compiled just in time.

Taking a step back here for a second to talk about ahead of time versus just in time compilation. I'm not too familiar with .Net outside of the compact edition but the performance of Java SE 6 is simply amazing, I've done enough high level C++ to know that Java SE 6 beats it hands down performance wise. Forgetting the ton of adaptive optimizations that the HotSpot virtual machine can do here for a moment, one of the major reason for this is the heap. Heap implementations in C++ are still based on C's malloc which isn't exactly good at dealing with tons of little polymorphic object allocations. C's malloc is still geared toward the C program, you allocate a bunch of memory at start up and you use that as a pool until your program ends. Not exactly friendly to a high level C++ program nor a multi-threaded one.

Getting back on track here, the lack of error reporting services unfortunately extend to the Java world. Even the tree major Java hubs out there, in addition to the tree named at the start of this post, namely, Apache and Codehaus do not provide crash reporting services. I guess Apache is off the hook since they provide mostly libraries and server software, but still, much could be done in the area of crash reporting.

All of this brings me to how NetBeans handles unhandled exceptions that occur in the wild. NetBeans pops up this little dialog and asks you to send in your report. Once you do send it, it's almost magical, reports are queued, analyzed, associated to either a new report or an existing report and finally the generic reports are associated to an issue in IssueZilla and it does it all automatically. If the issue is fixed, it even tells you in which, upcoming or not, version it has been fixed.

This is how it should be done. I don't know what license this system is under, but how about getting this into the greater community? Let's get this system moved from being NetBeans specific to all projects hosted at for example. And what's really nice about this is that it doesn't have to be limited to Java SE/EE, this can work just fine with Java ME too. Now, wouldn't that be something?

Friday, July 25, 2008

BlackBerry + WiFi

Taking a short break from the planned article list to rant about my new least favorite feature of BlackBerry OS.

If you have a BlackBerry that also happens to support WI-FI, you might be surprised to find out that your favorite networked application doesn't favor WI-FI over APN when you're in range.

In fact, these applications will never favor WI-FI over your regular data network link. This is because the BlackBerry operating system does not abstract this for the application programmer. In other words, unless the application programmer knows about this and explicitly codes support for WI-FI in his application, the application will never use WI-FI.

So how do you get WI-FI support in there? You have to append the magical string ";interface=wifi" to any URL that you want to open. So, assuming standard Java ME/CLDC network programming here, you would do something like:

String uri = ";interface=wifi";
HttpConnection c = (HttpConnection);

Otherwise, your application will inform you that "Could not open tunnel - Max time out" or go over your regular data link.

And that's about it. Oh, and by the way, if you don't have WI-FI or you're out of range, the OS won't do you any favors and fall back to your regular data link, so you have to make sure to try out the regular data link in case of errors too.

Finally, I would like to say that this feature is mostly impossible to find in the BlackBerry documentation. I found it in a beta version of an upcoming manual. The only reason I noticed this is that my development BlackBerry doesn't have a sim card, the browser worked, but my application didn't. Also of interest, almost all non first party applications I tested couldn't use WI-FI either. I'm guessing quite a few people don't know about this.

Sunday, July 13, 2008

GWT + j_security_check

I went out looking for a solution to this recently and found very little information. A lot of questions unanswered led me to believe I was not the only one who wanted to do this. I present here a small sample on how to accomplish this.


Before presenting the sample, let's go over a few things first on why you would want to do this and more importantly why you still need an Ajax style security token for all your GWT services even after this is implemented.

The reasons you would want to do this? One is automatic single sign-on (SSO) if supported by your container, e.g., Glassfish supports SSO out of the box for its web, EJB and web services tiers. If you use j_security_check, you're in; you're into all these services. Furthermore, if you use a J2EE authorization agent like OpenSSO inside Glassfish, you're into any services or sites provided by that federation. So even if you’re fronting your application with GWT, your back end might be composed of all these elements and more.

This also allows you to use any standard security annotations in your EJBs or, if you're orchestrating like me, in OpenESB. You can do this because you now have a Java security principal setup inside the container.

This also allows you to leverage the clustering features, if any, of your application server. Glassfish, again, contains great out of the box support for clustering. Session replication and expiration is managed for you and it just works. One call can proceed on one server while the other can proceed on another while the caller remains completely oblivious to where its work is actually being executed.


What you can’t do however is assume that you should no longer have an object representing your logged in user in your GWT client code. GWT RPC calls are still out in the open with this technique, you should pass in at the very least your session id value as a parameter to the GWT remote call so that the RCP service can do validations.


You still need SSL. Use SSL to make sure your password is transmitted securely over the wire. Hashing on the client side is completely useless. First, because MD5 is usually about the only thing available in JavaScript and that is easily broken. Second, because you should be counting on SSL to do its job correctly. Third, once on the server, you should hash your password with something that is secure, i.e., not MD5 and throw away the clear text representation of the password.


I use NetBeans 6.1 and release candidate 1 of GWT 1.5 for this example. The idea is to use the RequestBuilder class to touch a resource that has been marked off limits by the container. We do this because the j_security_check, in Java EE 5 at least, cannot be invoked directly in a portable manner. When the server sees the access to the protected resource by an unknown, it redirects you to the login page. When this occurs, the method “onResponseReceived” is called. We ignore the redirect and submit our own form. The form just needs to have at least 3 named elements present:

  • The form name, j_security_check
  • The user name field, j_username
  • The password field, j_password

If you don’t touch a protected resource first and simply submit your form immediately, you will find that you still don’t have a security principal since no login actually occurred in the container.


You would apply the same rules for defining a protected area than you would for a normal non-GWT application. You can see on how to do this in Glassfish and Tomcat by following the tutorial here.


Here is some sample code that fulfills a login on Java application server. I originally had more here in terms of error handling but it seemed it got to be too large for presentation purposes.


package org.codepimps.client;


public class MainEntryPoint implements EntryPoint {
  public void onModuleLoad() {
    final FormPanel formPanel = new FormPanel();
    VerticalPanel vpanel = new VerticalPanel();
    HorizontalPanel hpanel = new HorizontalPanel();
    TextBox userName;
    TextBox password;

    hpanel.add(new Label("User name:"));
    hpanel.add(userName = new TextBox());

    hpanel = new HorizontalPanel();
    hpanel.add(new Label("Password:"));
    hpanel.add(password = new PasswordTextBox());

    vpanel.add(new Button("Login", new ClickListener() {
      public void onClick(Widget arg0) {
        String url = GWT.getHostPageBaseURL() + "protected/protectedText.txt";
        RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, url);
        rb.setCallback(new RequestCallback() {
          public void onResponseReceived(Request request, Response response) {

          public void onError(Request request, Throwable caught) {
            throw new UnsupportedOperationException("Not supported yet.");

        try {
        } catch (RequestException ex) {
          // TODO present the error in a text area or something
    formPanel.addFormHandler(new FormHandler() {
      public void onSubmit(FormSubmitEvent event) {

      public void onSubmitComplete(FormSubmitCompleteEvent event) {
        // TODO actually make sure the login succeeded.  Present error in a text area
        // for the user to see
        Window.Location.assign(GWT.getHostPageBaseURL() + "/protected/protectedText.txt");



Wednesday, July 9, 2008


The blog has been very silent but I have quite a few articles in the queue coming up. Upcoming on this blog are:

I'm so busy I don't know when I'll have time to write any of these but hopefully they will be up before long.

Wednesday, June 11, 2008

Just How Bad is Windows CE?

Lately, I've been developing concurrently on the iPhone and Windows Mobile. The .Net Compact framework is actually pretty good compared to the iPhone SDK but the user interface of Windows Mobile is just so very, very awful. I can't think of anyone who has tried absolutely anything else and like this. I can't even think of anyone liking this period. Considering how good a job Microsoft is doing with its general and server operating systems, how is it possible that they are even willing to release this product in the first place? Considering the quality and usability of the desktop and server systems that Microsoft puts out, Windows Mobile isn't even worthy of calling itself Windows. Sure the underlying kernel and technologies are pretty solid but it doesn't change the fact that the user interface is just crammed for such a small screen. I was using this the other day just to make a call and kept thinking to myself how many people I know wouldn't even be able to answer or make a call with this thing.

The real problem with Windows Mobile is that it isn't trying to be a really good phone, it's trying to be a pocket PC which not so coincidentally was its original brand. It just doesn't have the screen real estate to pull that off.

At WWDC 2008, Apple announced 3G iPhones that are actually cheaper than the current models. This is bad news for every smart phone vendor out there. I see really two segments now, the people who just want a basic phone, and the people who want an iPhone. The iPhone is really just that disruptive of a technology. I can't explain in words just how horrible it is to start using another smart phone again. Furthermore, it's the only phone that I have encountered that makes mobile web browsing viable.

So what is everybody else doing? Well, you have things like Android and the Samsung Instinct which are clearly heavily influenced by the iPhone but neither are yet available. The iPhone 3G, with its 7 Mbps Internet access, goes on sale early July of this year.

All is not lost for other vendors however. Let's face it, even with its new focus on the enterprise with the iPhone, Apple is really not very good at dealing with businesses and developers at this scale. Those users won't put up with half the things the regular Apple fan boy puts up with. If you're in the iPhone developer program right now, you probably don't like Apple very much. The things they make you do to actually deploy an application to real hardware is pretty obscene. At this point, I think it's Apple's market to lose. We'll see if Apple will learn a bit of humility here and open up this platform instead of imposing their will on everything closely related to the iPhone. This is really where the door is open for something like Android to come in and really give iPhone a run for its money.

We'll only know for sure over time but Google, now more than ever, needs to get real hardware out into the wild and at the very least refresh the Android public SDK. The Android SDK drop is still the one from last March and, thanks to controlled leaks, doesn't look or feel anything like the Android of today.

So just how bad is Windows CE? Well, it's so bad I don't even think it's a contender anymore. Let's face it, convergence is still ever creeping in. In a few years, your primary computer will probably be your phone that you cradle to get a full sized screen and keyboard. This is already happening, just have a look at the Celio REDFLY. I would think this makes Microsoft pretty nervous.

Tuesday, May 6, 2008

The BlackBerry Curve

I have spent quite a bit of time dissecting this phone lately. The BlackBerry is certainly quite popular with some estimating its market share at 41% of all smart phones. On a recent trip to Pennsylvania, I saw many, many phones on planes and at the airports and I can certainly confirm that ratio. I counted close to 400 phones, half of which were some model of BlackBerry.

I have to admit, so far, this is the most impressive Java ME/CLDC capable phone found I have tried. Not only are many optional CLDC packages available but many more BlackBerry Java packages are present. That being said, Research in Motion (RIM), implements custom GUI packages that are specific to its platform. What that means is that if you code an application that follows the look and feel of a BlackBerry application, it will not function on any other phone.

I have to say however that this device is too expensive. At a suggested retail price upward of $400, it only features 64 MB of memory and an empty micro-SD card slot. A similarly priced iPhone comes with 128 MB of SDRAM and between 8 and 16 GB of flash memory. The iPhone screen supports touch and it's twice the vertical size of the Curve's screen.

The iPhone comes with Wi-Fi support too. Which means you can enjoy much faster networking on any hot spot and potentially save on those outrageously expensive over the air rates for bandwidth too. In Canada, MB per dollar access is ridiculously expensive. Rogers, for example, charges $10 per MB outside a plan. If you have a plan, prices range from $25 for 4MB per month to $100 for 100MB per month. Just disgusting if you ask me. Getting back on track here, you have expensive bandwidth and no memory to implement any kind of good caching on the phone. The only strategy left is to implement watered down services. Consider the browser on the BlackBerry for example, it has no JavaScript support and it mostly ignores any image properties found on a page in order to keep bandwidth consumption at a minimum. Sure, you can access the web but it doesn't mean it's any good.

RIM also develops probably one of the worst integrated development environments (IDE) you've ever seen. The JIDE is an all Java IDE that you use to code for the BlackBerry device. JIDE redefines what the word "ugly" means. Fortunately, RIM has started to develop a plugin for Eclipse and a plugin for Visual Studio. It's also possible to use NetBeans if you have enough energy to invest into it.

Looking at the BlackBerry, I have to wonder if the company suffers too much from the "not invented here" mentality and how much of that affects the price tag of its products. The company develops an IDE, customizes the licensed library and CLDC virtual machine from Sun, has its own executable format, implements its own content designers tools, etc, etc, all of which are very expensive. Talking to various colleagues these last few months, I am convinced that RIM must refresh its hardware in order to stay competitive. By refresh, I not only mean the power and visual appeal of their devices but the overall quality of the BlackBerry development platform or risk irrelevance.

Sunday, May 4, 2008

JavaOne is this Week

The Java front news has been dry for the last little while since everyone is holding off on announcing anything, instead waiting for the conference in the hopes of getting more press.

I'm really eager to see what will be made available this week. That being said, I'm hoping for major announcements on JavaFX from Sun. At the very least, I'm hoping to see some strong tooling support for content creation on that platform for graphic designers. Also, I'm expecting a new Java ME/CDC operating environment for phones based on the assets acquired from SavaJe and the PhoneME Advanced project. This new environment will feature JavaFX across the board.

Now, I still think Android is better than Java ME/CDC, but the CDC with all optional profiles is equivalent to Java SE 1.4 which is still pretty enticing. Furthermore, Java ME + JavaFX might go a long way to catching up with Android. By the way, PhoneME Advanced implements all the optional CDC profiles, so yes, it's equivalent to Java SE 1.4.

Thursday, May 1, 2008

Mac OS X 7 Years Later

Continuing my work in the mobile space, I recently had to purchase a Mac. By recently, I mean the day that Apple made their iPhone SDK public. I like the iPhone, it's the device that has raised the bar, the device that has forced all other mobile manufacturers to rethink their own product lines. We should see some real advancements this year from mobile hardware, that it be in terms of screen quality, power and features from competing companies thanks to the iPhone.

If the iPhone and iPod Touch are neat little devices, I have to admit I'm not much of a fan of Mac OS X however. I remember being so excited when I got my copy of OSX 10.0.0. That excitement was promptly crushed when I saw it under perform on my lowly PowerPC G3. After that, I pretty much left the world of Macs behind until the iPhone SDK was publicly made available.

The first I notice is how little has actually changed since 2001. OSX today is pretty much the same OSX that I used in 2001. The performance is much better of course but pretty much the same nonetheless.

I don't like the inherent security policies that are setup after install time. For example, to install an application, you usually have to start an installation wizard to guide you through the process. At one point during the installation, you're usually presented with a privilege escalation dialog. Entering your credentials will allow the installation to proceed. Unfortunately, the same cannot be said about uninstalling. First of all, there is no global registry of installed applications, so there is no uninstall wizard. You just go to the applications folder and drag an application to the trash to uninstall it. That's fine, my point is that you don't actually need to escalate to drop your applications into the trash. That's just plain wrong. Furthermore, it's only fine if this is where the application installed all of its files in the first place. Some applications will also install software in more traditional UNIX locations. If you happen to install such a beast, you'll be stuck with those extra utilities or have to rely on using a custom uninstaller before doing a regular uninstall. These custom uninstallers are usually Bourne shell scripts.

Speaking of escalation. Apple may poke fun at Microsoft about UAC in their commercials, but let me tell you they have nothing to brag about. First of all, they have an escalation prompt too, just like UAC. However, a filtered administrator, instead of a single click on 'Continue', must enter his password every time or optionally cache his credentials for a limited amount of time. Both options are terribly insecure. First, because if a malicious piece of software on both these systems makes a dialog box that mimics the appearance of this dialog, you get two very different results. On Vista, you have given out a mouse click (by clicking on 'Continue'), while on OSX you have given out your escalation credentials. Yeah Apple, keep making jokes. Furthermore, caching of credentials? Really? So everything I execute for the next little bit is running escalated? Really? At this point, I think OSX is only secure because it's less of a target than Windows, that's it, nothing else. It really has nothing to brag about. You can say all you want about the underlying UNIX security model found in OSX but if the user interface handles security this way, it's all for nothing.

I officially don't like Objective C. You can talk about the virtues of your favorite programming language all you want or not at all but it doesn't change the real reason some languages are popular and some aren't, in a word taste. Considering mostly all languages these days are Turing complete and object oriented, what a language looks like on screen is pretty much the only differentiator. When people like something, they have a reaction to it and they like it. Same thing when they don't like it. It's the same really for programming languages, when you look at a piece of code on screen, something in you reacts and decides if you like it or not, it really is that simple. When the dust settled, most people decided they didn't like how Objective C felt and used something else. Well, I'm now part of that group too except I can't use something else on the iPhone. I don't completely dislike it, e.g., I like the big class library and I like being able to retrieve the constructor of a class with nothing else but a string that represents the class name, I do, I really do... but that's about it really. The overly verbose method calls, the unified diff challenged syntax, i.e., '+' for static methods and '-' for instance methods is just plain evil when you're reviewing patches.

Using memory pools manually is also really just annoying. What is this? C or Objective C? I'm still not clear on how to correctly use these things across threads on the iPhone. I'm aware that the full OSX supports garbage collection now.

What I really despise however, what turned me off to Mac OS Classic and still does it for me today is the workbook style windows found in applications. If you've never used Mac OS, early versions of Visual Basic and Delphi suffered from this problem on Windows too. You have a single application but instead of being contained into a single master window, you have many little windows floating around everywhere. If you have multiple applications opened at the same time, you can see the windows of other applications within the holes of your current application. Most annoying is that there doesn't seem to be a standardized shortcut for quickly moving focus around between the windows of a single application. This makes use of Xcode really annoying. If I just happened to miss this keyboard shortcut, please, for the love of any deity you worship, please leave me a comment and tell me what it is.

Of course, it's not all bad. One very good feature of this OS is the startup and shutdown times. They both put Windows and Linux to shame.

The UNIX command line is a very nice touch too. I have to admit, as much as I like Vista, I don't think I could use it, or any other version of Windows for that matter, if it weren't for Cygwin.

Wednesday, April 16, 2008

Google's App Engine

Seriously, what happened? Python? I don't mean to offend anyone but why come up with this nice, huge, not to mention free, application server if all you're going to support is Python?

Now, I'm sure they are tons of people who like Python, I just happen to not be one of them. I don't like languages that are brace challenged. What's really annoying is that Google has been pushing its Web Toolkit(GWT) this last year, a toolkit that lets you write Java code for the client that gets compiled down to JavaScript so that is can execute on the client. Why is this not supported?

That being said, since GWT compiles down to static HTML and JavaScript files, it's still possible to use the client side, compiled product from Google's App Engine. The server end of the application would have to be written in Python. Furthermore, the RPC mechanism provided by GWT would need to be dismissed in favor of REST or JSON for communications.

All this to say that the top four requested features on the Google Code site for this project are support for other languages. I can understand Google not supporting Ruby, PHP and Perl. Google doesn't have any significant history with any of these languages. Java on the other hand? I just don't get it.

Wednesday, March 19, 2008

NetBeans 6.1: The Best just got Better

When it comes to IDEs, I've been around. I've used Visual C++ since version 1.5. Tried other environments over the years, but Visual Studio was by far the best no matter what other people claimed.

I started using Eclipse since that's what everyone around me was using for some Java work and I hated it. I'll reserve my thoughts on that for a future blog post but it was never a comfortable fit for me. Needless to say, I've converted my entourage from Eclipse to NetBeans now.

Version 5.5.1 of NetBeans was pretty good but the editor kept, well, I'm not quite sure on how to describe this, but it kept being wrong... or feeling wrong at least. Not sure if that makes any sense but that's the best I've got to offer.

NetBeans 6 was simply fantastic. It was just great. Probably one of the best IDEs I've ever used. That being said, it had a few shortcomings that were really annoying. On huge files, code completion was somewhat slow. Not that slow, but code completion is one of those features where you must literally work at the speed of thought of the developer. Otherwise, you break the flow of the developer. Startup time was annoying but manageable.

NetBeans 6.1 has really been great for me, so great that I've ditched 6 for the 6.1 beta. They are several reasons for this. First, it seems to me like this thing has had a lot more debugging time than a fully patched 6.0.1 release has. So it just works even if it's just a beta. That being said, a small caveat here is that I shun JavaScript work in favor of GWT. So I don't know how the rewrite has impacted that editor.

However, it's the little things that make the difference. For example, my favorite new feature by far is the default location of the Glassfish domain. Silly? Maybe, but I use Vista across the board. It has always been considered impolite under Windows to write to "Program Files" after installation has completed. Starting with Vista however, that folder has now been locked down. Meaning that with NetBeans 6, the default developer domain lived under "Program Files\Glassfish\domains\domain0". Under Vista, you had to either unregister your Glassfish server from the IDE and re-register it again with a more polite location, or you had to go into the Glassfish folder in "Program Files" and grant yourself write privileges to the domain's folder in order to support all scenarios. NetBeans 6.1 under Vista, and hopefully under any other Windows version too, creates the default domain inside your home directory. I think I almost cried when I saw that.

That being said, as much as I love this IDE now, ending a 14 year old run on Visual Studio/C++, I still have my pet peeves. In no particular order:
  • it's still slow to startup even it's a lot faster than it used to be.
  • I hate the fact that they are no project grouping feature similar to the solution concept in Visual Studio. NetBeans does actually have a project group feature but I just hate it. I hate it because it doesn't live on the file system, hence I can't commit it to source control. This means sharing project groups between team members is really annoying. I hate it because it clutters up the UI. The idea of a master project I find is also broken. Simply because you don't know right off the bat which of the project in a hierarchy is the master. I'm hoping that full support for Maven in NetBeans 7 will take care of this.
  • I use this IDE for pretty much everything now except for Windows Mobile and Android development. Which means I use it for C++ too. I don't use C++ that much anymore but it does come in handy. It works really well under Windows with cygwin, I even have Microsoft's Platform SDK hooked into this thing. Again, works pretty well. That being said, g++ is the only supported compiler under Windows. Considering the Visual C++ compilers ship with the Platform SDK now, I would like to be able to just use those instead of g++.
  • I would like to be able to run multiple instances of the IDE at the same time. The scenario here is when I want to debug both the client and server end of an application at the same time.
  • Better GWT support. Matisse is great but with all these new languages and toolkits like JRuby, Groovy and GWT coming into the Java ecosystem now, isn't it about time this thing started to learn new tricks? Look at SharpDevelop for instance. It has a visual form designer for all the languages it supports.
  • Message queues in the services tab. I really like the services tab. I really like the fact that databases are showing up there too now with this release. The Java DB menu item looked out of place in the tools menu in 6. Support for stand alone instances of JMS brokers would be a welcomed addition. I use Glassfish a lot, but I also use ActiveMQ outside of any Java EE container a lot too. Why? Because of the additional interoperability features it provides. Very handy to have around. And yes, before anyone comments on this, I know about the STOMP adapter from CodeHaus could probably be installed on OpenMQ.
  • Support for Groovy, Groovy and Groovy.
  • Lastly, I would like to see a Geronimo server plugin. Yeah, I know this a weird one considering I'm all Glassfish. However, I have one project where Geronimo was the best compromise I could reach. Maybe this is selfish but in my defense, I would probably have started coding this if it hadn't been for this thread here.
All in all, I'm pretty happy. I won't be switching back to Visual Studio anytime soon. The only real problem I have with NetBeans is that since everything is in the open and announced upfront, I find I'm always eager to get my hands on the next release, never truly satisfied with the current one. I would imagine however that's a good problem for NetBeans to have.

Monday, March 17, 2008

TopLink Lives

It was my hope that the union of BEA and Oracle would lead to the enventual demise of TopLink in favor of KODO(Apache OpenJPA). Obviously, Oracle being and enterprise player, any phase out plan would be over many, many years. For example, I think Oracle will move their customers to the vastly superior WebLogic over their own Java EE offering but will still probably continue to offer and develop OC4J for many years to come. However, when it comes to a Java EE server, they are many parts. Each part could conceivably be marketed and sold individually.

Of course, things were never that simple. The core of TopLink, TopLink Essentials, is the JPA version 1 reference implementation, is open source and ships with Sun's Glassfish server which also happens to be the Java EE 5 reference implementation.

Futhermore, Oracle donated not just Essentials but the full TopLink product a while back to the Eclipse foundation under, curiously enough, under a different, Eclipse compatible, license.

Today comes the announcement that TopLink Essentials is indeed being phased out but TopLink is moving up in the world. The full TopLink, the one donated to Eclipse, is now EclipseLink. EclipseLink has been chosen as the JPA version 2 reference implementation and will ship with the next version of Glassfish, also know as the Java EE 6 reference implementation.

All in all, this is good news nonetheless. The double donations, under different licenses no less, being consolidated in one code base is certainly less confusing. The Eclipse license, from EclipseLink, is also more permissive than the CDDL/GPL from TopLink Essentials. In fact, so permissive that the Apache Software Foundation considers it just fine too. For example, the Java compiler from Apache Harmony is actually the Eclipse Java compiler.

Now, if we can just get comprehensible error messsages from future releases, all should be good. That being said, I've been using TopLink Essentials more and more, and after a while, you get into this weird Zen state and actually start to recognize and understand the error messages. When you do, it actually works pretty well. That being said, I still think those error messages are nuts.

Tuesday, February 26, 2008

I'm Tired of Closing Files

Not long ago, color commentator Bruce Eckel shocked the Java world with his article entitled: "Java: Evolutionary Dead End".

The press went wild stating that Java was doomed since one of its biggest supporters was now shunning it. If you actually read the article, this doesn't call for the end of Java, just slowing down or completely stopping the adoption of new features to the language akin to what C and C++ are today. C and C++ are governed by slow ISO committees that make a new language specification every ten years or so. Instead, he argues, hit the reset button and make a new language on top of the JVM. Certainly, the JVM is no longer a stranger to non-Java languages, both Groovy and JRuby seem to be carving a niche for themselves.

Furthermore, the Java virtual machine, at least the one from Sun, is constantly improving both in terms of speed and memory consumption. The version 6 virtual machine of HotSpot from Sun is nothing short of spectacular. New language, same great infrastructure, sounds perfectly reasonable doesn't it?

Now, why would he choose such a tittle? I'm familiar enough with this author, I probably still have the 1st edition of Thinking in C++ somewhere, to know that it was probably on purpose. He knew the
attention he would get with this kind of title than with one that more accurately portrayed the contents of his article. Nonetheless, it made a lot of people think about the core issue, should Java be frozen or not?

I've been thinking about that lately and I've come to the conclusion that I'm tired of closing files or any other type of resources for that matter. I think it's reasonable to freeze Java (the language)
but only after it has indeed reached adulthood. You can talk about Java 7's closures, asynchronous I/O and super packages all you want but it doesn't change the fact that I'm still sick of closing files.

With a garbage collector present, it is no longer clear when the destructor/finalizer of a class will execute. If I were to write a program that operates on files, I would have to manually close any file object created or risk running out of file descriptors depending on the operating system I am running on. The same can be said for any object that holds kernel level resources. Coming from C++, this is something I no longer needed to care about, why should I care about it in Java?

C# does something interesting here, any object that implements the IDisposable interface can be used inside a "using" statement. This means that at the end of the "using" block, the dispose method is automatically called. Something like this:

using System;
using System.IO;

class Program {
static void Main(string[] args) {
using (Stream stream = File.Open("foo", FileMode.Open)) {
// Operate on stream to foo
The problem I have with that is that it's still bound to one variable per "using" block. So, to copy a file to another, I need at least two "using" blocks.

In C++, the resource initialization is acquisition idiom is increasingly popular, made even more popular by the use of smart pointers, so assuming the use of shared_ptr here:
if (shared_ptr<x> p = someManager.get(id)) {
// operate on p
} else {
// p is also not in scope here
// p is no longer visible

All this to say, that the equivalent construct is missing in Java. Not only, but I don't like the C# solution as it's possible to go further.

If you have multiple "using" (or "if") blocks, why can't we just make a list? In other words, if I can acquire this list of resources, then execute the block otherwise don't? For example:
// Fake Java code sample
using (FileChannel r = new FileInputStream(path).getChannel(),
WritableByteChannel w =
Channels.newChannel(response.getOutputStream())) {

r.transferTo(0, length, w);
} finally {
// handle failure
Instead, I have to do something like:
// might throw
FileChannel fc = new FileInputStream(file).getChannel();
WritableByteChannel w =

if (w != null)
fc.transferTo(0, file.length(), w);

// null or not, w is still in scope
// Don't really have to close, but waiting for GC might be fatal later on
I write a lot of Java code now and I'm really enjoying it, I wouldn't go back to C++ at this point. C++ is only the last resort language now, the language that makes things work if it doesn't anywhere else. So, when I hear things about freezing Java, I think about things like this. I wonder how much time Mr. Eckel spends writing code versus teaching it. As an educator, I can understand the importance of a non-moving target, but in the field, I need relief for some common idioms. Saying let's do a new language won't make all the tooling that's available today for Java suddenly appear on that language. For example, I really like Groovy but I don't use it. The IDE support in NetBeans just isn't good enough for me to work with it.

BDJ Revisited

My last blog entry talked about Blu-Ray Java a.k.a. BDJ. Hanging out in the groups however, not all is well in the land of BDJ.

The first problem is fragmentation. BDJ is really young and the fact that fragmentation is already a problem is something I find completely unacceptable. Fragmentation means that either the reliability or availability of the code that ships with the device varies enough that you have to change your application code to work around bugs or missing features. In layman's term, it means you need to ship different SKUs and that costs money. Money to package, money to validate and money to distribute. Java ME fragmentation has really gotten out of control these last few years. The Transformers movie tie-in game is one of the biggest Java ME project ever undertaken. In all, some 25,000 SKUs shipped in order to support all the phones out there. Yes, that's 25,000, twenty five thousand SKUs. I can only imagine what the cost of getting that game to run on all these handsets was. No horror story of this magnitude in the land of BDJ yet, however the "Chicken Little" movie application apparently had 30 different variants in order to run.

Not all is lost however. Unlike Java ME (CLDC or CDC variants) on phones. The Java ME/CDC stack that is shipped with BDJ is upgradeable. If your device is networked, it can phone home and check for upgrades. If your player isn't networked, upgrades can still ship with a movie disk. I'm not sure what the experience is for the end user considering most users won't even understand what this is upgrading in the first place but let's hope it's very transparent.

For the moment anyway, this needs to be dealt with. Content authors are overwhelmingly choosing HDMV for their content over BDJ. Only 30 of the 600 or so Blu-Ray movies that have shipped, i.e., roughly 5%, use BDJ.

It could be just familiarity with HDMV since these authors have been using it for quite some time on regular non-HD disks, or could it be the complete lack of tools? This being the second problem. I've blogged before about JavaFX. JavaFX is many things, but what it really is a codeword to right all the past wrongs of Java on the client. So, even if we haven't seen any JavaFX authoring tools for designers, Sun has confirmed that it's working on components for Adobe products to output JavaFX scripts. Now that could be something that is enticing for content authors. The HDMV tools don't even come close to the Adobe design tools.

Finally, my last gripe is why did anyone even bother with Java ME in the first place for these devices? For crying out loud, these devices can decode and output 1080p video. I think they can handle the full Java SE platform. Considering that Sun has announced their intention to eventually phase out Java ME over the next decade to converge with Java SE, did they really have to add another few hundred million devices as part of that phase out plan?

Tuesday, February 19, 2008

HD-DVD is Dead. Where's the SDK for BDJ again?

So, it finally hit the fan. Toshiba has ended its HD-DVD business. This obviously impacts consumers since most people have wisely decided to stay away from this market until one format won out against the other.

What consumers don't know about these mortal enemies is that this war was being fought on two fronts. The other front being software, mainly codecs and platforms. Unbeknownst to the regular DVD Joe and Sally, all Blu-Ray players are shipped with Java ME.

Considering the horror that is Java ME on phones, you'll be happy to know that the Java ME that ships on Blu-Ray devices is the CDC profile. The CDC profile has considerably more features than the CLDC one that usually ships on phones but still falls short of .Net Compact and Java SE. Unfortunately, the CDC still has many optional packages too which means that fragmentation card is still in the deck. I'm not sure anymore if .Net Compact was shipping on HD-DVD players, information on the subject is very scarce but my belief is that it was. I know for a fact that .Net Compact ships on the X-box 360.

Officially, the Java that ships on Blu-Ray is called BDJ and they are basically two profiles, one that offers networking and the other one does not. So, for example, the Java that ships with the PS3 is BDJ with networking. Well, all these features are basically meant to offer a richer interactive experience on BR disks. However, with the rise of casual gaming and the presence of USB ports on most of these devices, I wouldn't be too surprised if some games started coming down the pipe using this technology. The problem so far has been about getting an SDK. In other words, BDJ has not been widely available since the movie studios aren't sure if they want developers writing code for these devices. The fear is that these SDKs will be used for cracking the copy protection of disks.

Well, I don't know if this coincidental or not, but we are finally starting to see BDJ related bits being made publicly available. You can see a introduction to BDJ from its main architect here. The HD cookbook project is also available from

So what does this all mean for consumers and developers? Well, if you bought an HD-DVD drive, welcome to the world of betamax. If you bought a Blu-Ray player, congratulations, you'll be able to get content for many years to come. For the Java developer, it means yet another way to leverage your existing skill set. With potentially hundreds of millions of Blu-Ray players that will be sold in the next few years, you have yet another avenue to market applications. For the .Net Compact developer, you still have a small, but sturdy niche of Windows CE based smart phones that you can still code for but that's about it.

Sunday, February 17, 2008

No More Heroes Again

I just finished the game. This is what fun is all about. In any case, I want a sequel. So go buy it. If you don't own a Wii, there's never been a better excuse.

In any case, if you have played the game and are wondering what Jeane was talking about at the end, it's available from YouTube. No wonder it was fast forwarded in the game, that "M" rating would have turned to an "AO" one real easy. If you haven't played it yet, don't watch it, it spoils pretty much the ending.

Monday, January 28, 2008

The magic of the tablet

This blog post is special, it was all written by hand. That is, it was written using a Tablet PC running under Vista.

You know, people all around me are always complaining about how bad my penmanship is, but this thing is pretty good at figuring out the words that I'm writing.

So kudos to Microsoft how figuring out my bad writing. That being said, there's one slight problem. You know those toolkits that have custom widgets that do their own drawing? For example, Qt, Java swing and Mozilla based products to name a few, well, they don't work.

The problem is that the handwriting controls are tied to the native window class. So, if you have a window that has a native class of "text box", then Windows knows to pop up the handwriting widget button. When doing custom painting with widgets, the native Win32 class for all windows is, well, "window". So Windows can't tell that it's supposed to put up the handwriting pop up.

Too bad, Sun is really trying to position Java for rich client Internet apps. Is this important? Maybe, maybe not, but this is definitely something that the .Net Framework can do. Sun now has a lot of people working in Redmond to make Java run on Windows better. Well, this is one item that they can put on their todo list.

Wednesday, January 23, 2008

No More Heroes

This blog is usually about technology but every once in a while, a game pisses me off and I write bad things about it here, i.e., Resident Evil: The Umbrella Chronicles.

Even more rarely, I get to experience a real gem and it does take quite a lot for me to actually write something about it. After all, a lot of good games came out in 2007 and I didn't bother to write anything about the majority, if not all, of them.

No More Heroes, just released exclusively for the Wii, is such a gem. Do yourself a favor gamers, pick up a copy. You can see a video review here.

Sunday, January 20, 2008

Oracle Buys BEA

If you haven't heard by now, Oracle has just acquired BEA for a lot of money. Here's what I'm hoping will come out of the deal, or at least some predictions:
  • TopLink dies a horrible death replaced by KODO.
  • TopLink Essentials dies a horrible death replaced by KODO core (Apache OpenJPA).
  • Oracle OC4J still doesn't do Java EE 5, it's still stuck on Java EE 1.4. It has almost no market share and BEA WebLogic has something like a 33% market share of application servers. Not sure what will happen here...
  • JRockit will hopefully die a not so horrible death. JRockit is a full Java SE implementation but it's actually licensed from Sun with some custom patches applied that apparently improve performance. Enough already, if those custom enhancements are really worthwhile, just contribute them to the OpenJDK project already and move on.
  • IDEs? Don't know what will happen there, both companies have their own Java IDE which have both failed to gain any significant momentum. To me, 0 + 0 is still 0. Here, please note that I am talking about market share and not the quality of these products
KODO was acquired by BEA which donated the core bits to Apache which formed the OpenJPA project. OpenJPA is now used by WebSphere, Geronimo and WebLogic. Having OpenJPA standard in Glassfish would be nice but even if Oracle decides to move forward with KODO, it still doesn't mean Sun would decide to dump the TopLink Essentials code that Oracle contributed to Glassfish. Well, here's hoping, see my previous blog post on TopLink Essentials on why I think this matters.

Tuesday, January 8, 2008

Frustrated Android

Well, I've been coding some mobile demo applications up recently. Not much really, just a message of the day application on a server that offers SOAP and Restful services.

The idea is to showcase a mobile client for each of the major toolkits out there i.e., Java ME (CDC and CLDC), .Net Compact and Android.

Well, it has been a lot tougher than I thought, every one of the platforms had hurdles except .Net Compact. In Java ME, both editions didn't have anything to parse XML. No big deal, had to pick up a 3rd party open source library but it's a good thing the server had Rest and not just a SOAP API. Microsoft .Net Compact was just a charm to work with. Really no problems. In all, it took 1 hour for the .Net client, 4 hours for the CDC client and about 6 hours for the CLDC client.

Enter Android, I was really eager to start work on this client. Java 5 syntax. Most of the Java 5 platform classes. What could possibly go wrong?

Well, the first problem is the IDE. NetBeans isn't supported. You can say what you want about the NetBeans vs Eclipse debate but NetBeans 6 is a killer application. Going back to Eclipse hurts.

The second problem is the complexity of the user interface building blocks. What I mean by that is that you can't just have a combo box and fill in some data for example, you have to setup an adapter that wraps around your data and plug that into the combo box. I'm all for flexibility but too often this is overkill. Not enough common adapters are provided in the platform. I think this is a real issue. Look at Qt 4, it suffered from the same problems, great flexibility in its models, but to do even the simplest of task meant huge amounts of coding. Trolltech introduced common model classes in subsequent releases of Qt 4.x to address this. I really think Google needs to do the same here too, just too much of a pain to fill in widgets when you don't need flexibility.

Where do I report bugs? Because I encountered a lot. No public issue tracking system is available.

The documentation has issues too, most of the time I just had to guest what a return value of an adapter method had to do. Also, I can't find anything recommendations on how to use threads on this platform or should they all just be shunned in favor of Android services?

All in all, it was a very painful process. I wanted this to be my favorite platform and I ended up cursing at it. At this point, I've spent two days on the Android client and I'm done for now. I'll pick this up again when Google refreshes their SDK.

Now that the dust has settled, I find it a bit unsettling that .Net Compact 3.5 was by far the best mobile platform. Competition with .Net has really made Java SE and EE superior products, but where are the Java ME improvements? What's really annoying too is that my .Net client can run as a rich client and Silverlight application without modification, just different build settings. I know, I tried, it works.