All posts by shannah

Steve Hannah is a 28-year-old software developer currently studying and working at Simon Fraser University in beautiful Vancouver British Columbia. He specializes in web information systems and prefers Java, PHP, and Python as programming languages. He is a Christian and worships at Christ Church of China in Vancouver.

Develop for Mobile or Die!

If you develop software that is designed to be used by Humans, then you are now required to develop mobile-friendly user interfaces.

In 2011, a mobile user interface was a luxury. In 2012, it was a nice add-on. In 2013, it is a requirement, or your software will be headed for the junk bin. Smart phones are now ubiquitous, and tablets are taking the place of the laptop in many contexts. People are becoming savvy to what can be accomplished with a tablet, and their expectations have been significantly raised for all software that they use.

Of course, the desktop (i.e. computers with mouse or trackpad and keyboard) is not going anywhere. It is just being reserved for those heavy-duty tasks that cannot be performed with a touch device like (and this list is shrinking every year) video editing, software development, and word processing. One class of application this can now be handled wholly via a mobile interface is the CRUD application. And if it can be created for mobile, it should be created for mobile – or your users will complain (either silently by seeking out other solutions, or loudly in email).

One trend that I noticed in 2012, was a shift of user gripes originating from users using IE to users on mobile devices. At first, my canned response was: “please use a computer, not your iPad, for using this database”. Of course, the software worked on iPad, but it wasn’t optimized for the platform so it was a little painful to use. And even under the best of conditions, users will find a way to break a UI. At first, there were some valid reasons why the app had to be used on a computer. But at this point, there are no longer any technical barriers in the way of providing a mobile interface to a (mostly) CRUD application.

Transitioning CRUD Applications to Mobile

The easiest way to transition a CRUD application to mobile, is to use an HTML library like jQuery mobile. It provides a slick UI that is very similar to native. The simple act of adding a UI in jQuery mobile that is tailored specifically for mobile users will eliminate most gripes. The larger buttons and fields, combined with a more familiar mobile workflow will make your users much more at home inside your application.

Unfortunately, the similarity to native applications will invariably lead your users to start requesting features that they have seen in other native applications. E.g.:

  • We want to be able to take videos with our phone and upload them into the database. Can we do that?
  • We want to be able to use the database without being online. Can we do that?
  • We want the database to be able to track our movement and velocity and store this in the database. Can we do that?
  • The application is kind of sluggish when loading pages and scrolling, etc…. Can you improve it?

The list of feature requests is not even limited to things people have seen before … the possibilities are endless.

While HTML5 is improving all the time, and it does technically support offline apps, and limited video access, it is still very flaky, and does not approach a native experience yet. Ultimately, when your users start asking for native-like features, you need to start looking for a way to build an application that is treated as a first-class citizen on the mobile platform of choice.

Mobile Platform of Choice??? Do I really need to Choose?

The next step after outgrowing your HTML5 mobile interface (with jQuery Mobile), is to look at your options for developing a native application. I’m using “native” in a very loose sense here. Really what I mean is an application that is installed on a mobile device in the same way as the platform’s native applications. This could be an application that is written directly using the platform’s SDK or using some other toolkit that ultimately builds an application that can be installed on the device.

If you are developing a CRUD application for an organization (like I usually am), you may or may not be able to dictate that your users use a specific device. In my case, I usually can’t… or if I try it is a world of pain dealing with people that use “the other” platform. Therefore, developing separate applications for each platform is not really an option (or good use of resources). I’m still choked at having to venture outside the web-box, much less create multiple versions of the same app.
At the minimum you’ll need to develop versions for Android and iOS (but BB and WinPhone users might get on the gripe-wagon, so watch out!!).

Phone Gap

As a web developer, naturally, the first thing I looked at was Phone Gap. It allows you to develop your application using the same web tools (HTML/Javascript/CSS) and deploy it as a “native” application. The native application is essentially just a thin wrapper around a web view component. It provides some additional libraries for working with the device’s hardware like accelerometer, GPS, video camera, etc.. Because it is just a web view wrapped in an app, you can use all of the same libraries (e.g. jQuery Mobile if you like) for developing the app. If you’re lucky you won’t have to modify the existing web app at all.

Building the applications for Phone Gap can be a little more involved, as different platforms need to be set up differently, and some even differences in the application code to make it work. However, the PhoneGap build service is available to provide building in the cloud for multiple different devices. This should ease the “pain” substantially.

Phone Gap will probably give you enough flexibility to add most features you need in a CRUD application. However, you may run into issues with performance. Javascript/HTML runs much more slowly (and noticeably so on low-powered mobile devices) than native code. Facebook’s shift away from HTML5 apps to native apps last year is a key indicator that, for mobile at least, HTML5’s time has not yet come. This performance will be most noticeable when performing scrolling operations and in some transitions, but it can rear its head anywhere.

To make matters worse, on iOS, the UIWebView component doesn’t use the same Javascript engine that is used in the Safari web browser. It is substantially slower. So, by moving your application from the Web into a PhoneGap app, you will be facing a performance penalty directly from Apple.

If you are running into performance problems, or you require native features that just aren’t offered in Phone Gap, you may need to graduate to the next level: Real Native Apps

“Real” Native Apps

First, let me define what I mean when I say “Real” native apps. I mean applications that are compiled down to native executables on the supported platform. I disqualify Phone Gap from this category (and the many other HTML5 in WebView solutions) because the actual code is running inside a web sandbox.

If you have reached this level, you should at least take the various platforms’ native toolkits for a spin so that you understand how they work. Each platform offers its own unique vision for their mobile worlds. And some concepts don’t transfer easily from one platform to another. Developing for iOS is very similar to developing for Mac OS X. You use Xcode and Interface builder to develop your application logic and user interface. Generally the entire user interface is contained inside a single Nib file, and you can use the many UIController classes to control the user interface. iOS includes many useful frameworks such as CoreData which makes it easier for you to develop CRUD apps on iOS.

Android, on the other hand, is an XML jungle. The UI is defined in XML files, and so is the application configuration. It is a much more open environment than iOS, in that it is set up to encourage applications to share its components with other applications on the system.

Blackberry and Windows Phone provide their own models, but I’m not familiar with either of these platforms.

In the course of auditing the respective SDKs you’re bound to observe the elephant in the room: All of these SDKs use different programming languages. iOS uses Objective-C, Android uses Java, Windows Phone uses C# (or C++ depending on version), and Blackberry uses C++ (at least for BB10… older versions use Java).

This makes it very difficult to share code across multiple platforms. Since I don’t have the resources to maintain separate code bases for each platform, I need to either pick a single platform and run with it, or look for a solution that will allow me to develop for all of the platforms with a single code base (remember I have disqualified Phone Gap and its HTML5 ilk already if I have reached this point).

Luckily there are options:

  1. MonoTouch provides C# bindings for pretty much the entire Cocoa Touch API (iOS). It also provides bindings for Android.

  2. J2ObjC is a tool developed by google to convert Java code to Objective-C so that it can be reused for iPhone development.

  3. Oracle ADF provides a full development toolkit that allows you to build for most mobile platforms. It uses an embedded JVM for business logic, and Phone Gap for the UI…(should we disqualify this out the gate because of Phone Gap?)

  4. Appcelerator Titanium provides a cross-platform solution that provides Javascript wrappers around native components. It is different than Phone Gap in that it doesn’t run inside a web view, it merely uses the native platform’s built-in Javascript interpreter and bindings to access native components.

5. XMLVM is a low level converter that allows you to convert code between many different languages. It provides compatibility libraries for working with Android and iOS. In my opinion, this is the most ingenious software development of the past 10 years.

  1. Codename One. Codename One allows you to write mobile applications in Java and compile them into native executables for most major platforms. It uses XMLVM under the hood for its iOS port. This is, by far, the best option right now for cross-platform native mobile development, and I’ll explain why in the following section.

If you know of other options, please let me know.

These solutions can be grouped into 3 categories:

  1. Tools that assist in porting from one platform to another, but don’t provide a full development solution. These include J2ObjC and XMLVM. While these are very interesting projects, it our aim is to be able to build a cross-platform web app, then these projects won’t get us there directly. If you are developing a tool or SDK that is designed to help you and others build cross-platform apps, then these projects may be of great interest to you.

  2. Tools that allow you to share your business logic between platforms, but ultimately require a rewrite of the user interface for each platform. MonoTouch falls into this category. Really MonoTouch is a solution for C# developers who want to develop for iOS and would prefer to use C# instead of Objective-C. It isn’t really a solution for building cross-platform mobile applications.

  3. Tools that provide a full solution for developing cross-platform mobile applications. Codename One, Oracle ADF, and Appcelerator Titanium fall into this category.

Oracle ADF

I have watched videos and read documentation for Oracle ADF, but have never actually tried to build an application with it. There are a couple of show-stoppers for me on this platform:

  1. It is commercial. I wasn’t clear on the license costs, but it makes it sound like they are hoping to make large license fees off of large enterprises.

  2. They use Phone Gap for the UI. If I’m at this point (looking for a native solution and Phone Gap won’t cut it), then, ADF doesn’t meet the requirements.

Appcelerator Titanium

Appcelerator Titanium is a clever project. I spent some time last year using the desktop version to develop some desktop applications using Javascript and CSS (the desktop version actually works more like Phone Gap than their mobile version does… it embeds a web view in a native window). Ultimately I abandoned all of my desktop Titanium projects as it was apparent that the Appcelerator people were putting all of their development resources into their mobile edition and letting the desktop version languish.

The mobile edition has some promise and apparently it has their full weight behind it. The concept of using Javascript bindings for native components is interesting, although it leaves open some of the same performance problems that plague PhoneGap. From what I have read in various forums and blogs, Appcelerator mobile apps do run into performance and memory problems if they are not developed carefully. Although they seem to be getting better with each release.

Appcelerator provides an API that generalizes commonalities between different platforms, but it enables you to write plugins that are platform specific if you need to use features of a platform that aren’t available in the API. This blog (presumably by someone who knows titanium – “titaniumninja”), argues that Appcelerator isn’t really a “Write Once Run Anywhere” tool:

Titanium isn’t a write-once-run-everywhere platform. As Appcelerator’s guys use to say, its aim is to be a write-once-adapt-everywhere tool, since, while using a common high level language and API, it enables the exploitment of platform specific features when needed. This philosophy is clearly visible in the API, as we have entire sub-namespaces dedicated to either iOS, or Android. This allows adapting our mobile applications to the platforms where they’re executed, thus avoiding a write once, suck everywhere effect. Moreover, the possibility to develop custom native extensions to the framework opens up a wide range of development scenarios, ideally allowing us to create user experiences that are practically undistinguishable from those of applications developed with native SDKs.

This description/warning seems realistic and makes me optimistic about the platform. If you are a Javascript/CSS ninja, then Appcelerator will probably provide an accelerated path to a mobile application, while not inhibiting you with a glass ceiling. I really like to be able to build native plugins for high-level frameworks. Otherwise I feel like I’m one feature request away from having to abandon the platform.

Without having dug too deeply into Appcelerator’s API, there are a couple of negatives (when compared with Codename One or native app development) that appear right off the bat:

  1. Javascript is a bitch to debug compared with managed languages like Java and C#.
  2. Memory management and performance are likely issues, and you may need to dig into the “native plugins” crutch sooner than later to resolve such issues.

If Appcelerator was the only cross-platform solution on the market, you can bet I’d be using it.

But Codename One exists…

Codename One

I have been developing with Codename One for a couple of months now. Based on that, you would probably guess that it was my choice for developing native mobile apps. You would be correct. When you line up all of the other options for development (native SDKs, Appcelerator, ADF, etc..), Codename One wins on almost every front.

What do I like about Codename One?

Codename One is the only true write-once-run anywhere solution out there (for native apps). It uses OpenGL (I believe on all platforms, but any graphics toolkit could be used if something better came along) as the foundation upon which its rich set of components are built. This makes it much easier to port to different platforms than, say Appcelerator, because all of the widgets are light weight (Similar to Swing in the Java Desktop world). The user interface can be styled using themes to look exactly like the native platform, and they provide native themes for all platforms for which they produce apps.

Applications are written in Java and they are compiled into native binaries (on iOS they use XMLVM to produce native C code that is compiled into an ARM binary using LLVM). They provide plugins for Netbeans and Eclipse, as well as a simulator to be able to run and preview your apps right in the IDE. The resource editor application also provides rich GUI development tools for forms and themes.

Basically, they have provided for the entire development cycle. They don’t leave you hanging. They even provide a cloud build server for you to build your applications without having to install the native SDKs. This allows Windows users to build iOS apps, and Mac users to build Windows Phone apps. (Initially I was concerned that I wouldn’t be able to do my own builds offline, but this was unfounded, as I was able to, without too much difficulty, set up my own build environments for iOS and Android… and I have no reason to believe it will be any more difficult for Blackberry).

The performance of CodenameOne apps is near native, and may even be faster than native apps in some case (e.g. Java method calls are 3 to 4 times faster than Objective-C message calls).

All of these features (the GUI builder, simulator, build server, Netbeans plugins, etc..) was enough to make me try it. But I stayed for the API. CodenameOne’s API is a joy to use. Their founders have a real knack for building clean UIs that are easy for developers to figure out. It appears to be heavily influenced by Swing, but with all of its demons exorcised. As an experiment I set out to write an application using the Android SDK, the iOS native SDK, and Codename One separately to get a feel for the differences in the API. By far, the Codename One API provided the most fluent experience.

In places where the API doesn’t support something, Codename One provides native interfaces that allow you to develop your own native libraries that interoperate with Codename One. This means there is no glass ceiling. Anything you can do on a native platform, you can do on Codename One.

If you are a Java developer, you really should be using Codename One to develop your mobile apps. Otherwise you are wasting precious resources and excluding potential users and platforms from enjoying your application.

If you are not a Java developer, and you want to develop mobile apps, I still think that you would be better off learning Java and jumping on the Codename One wagon than spend your time developing for another platform.

Codename One iOS Offline Build Project

To build upon my last post, I have encapsulated the steps to build an iOS application offline (i.e. without having to send to the CodenameOne build server) into a single ANT script that can easily be installed on your local system, and imported into the build.xml file of your CodenameOne application.

The CodenameOne folks have provided me with space in the CodnameOne incubator subversion repository to host this project so it will be available to everyone.

Synopsis

The Offline Build Tools project includes some scripts to perform the building of CodenameOne applications on any computer running Mac OS X 10.7 and Xcode 4+. The applications it produces should be equivalent to those apps produced by the build server in every way (including Native Interface support). Please let me know if you run into any cases that the build tools do not support).

Installation

Before you can use the offline build tools in your Netbeans project, you need to install the build tools project. You only need to do this once. Installation involves only two steps:

  1. Check out the offline-build-tools project from the SVN repository:
svn checkout https://codenameone-incubator.googlecode.com/svn/trunk/shannah/offline-build-tools codenameone-build-tools
  1. Run the ant install script:
$ cd codenameone-build-tools
$ ant install

This will check out the entire CodenameOne SVN repository into the “tools” subdirectory so that it can be used for building your projects. It may take some time to complete as the SVN repository is quite large.

When the installation is complete, you should notice that it created a file named “build-ios.xml” inside the codenameone-build-tools/dist directory. This contains a ready-to-use ANT target that can be imported into the build.xml files of your CodenameOne applications.

Adding the “build-for-ios-device-locally” Target to Your Netbeans Project

Now that the Offline Build Tools have been installed, you can freely add the resulting ANT target to your CodenameOne application. If you haven’t already done so, you’ll need to create a CodenameOne project in Netbeans (e.g. File > New Project, and select “Codename One” as the project type).

Under the “Files” tab in Netbeans, you should be able to see and open the “build.xml” file for your project. Just add the following <import> statement anywhere inside the <project> tags of the build.xml file:

<import file="/path/to/codenameone-build-tools/dist/build-ios.xml"/>

Now, if you right click on the build.xml file, and select “Run Target” > “Other Targets”, you will see a target named “build-for-ios-device-locally”. Select this target to build your project.

Alternatively, you can build from the command line using:

ant build-for-ios-locally

Note: If building from the command line, you may need to set your JAVA_HOME environment variable to point to your JDK’s Home directory. e.g.

export JAVA_HOME=/Library/Java/JavaVirtualMachines/1.7.0u10.jdk/Contents/Home

If you’re not using CodenameOne yet, for building mobile apps, you really need to start. It is the only solution that currently allows you to write apps for all major platforms in a performant way.

Disclaimer

This project is meant for development purposes. I created it to allow me to be able to test and develop patches for CodenameOne without having to submit them to the CodenameOne people to be applied to the server. The current settings work directly off of the CodenameOne trunk, which is probably not ideal for production apps … it is bleeding edge.

I recommend using the CodenameOne build server for all production builds as it has been refined with (probably) some optimizations, and it makes it much easier to build on many different platforms with great ease.

Building CodenameOne iOS Apps Locally

Note: This post discusses the mechanics around building CodenameOne iOS projects locally. See my subsequent post for information about a project that automates this entire process.

I’ve been playing around with Codename One quite a bit recently, as it appears to offer enormous potential in the field of mobile development. One initial stumbling block that I had with CodenameOne was that you needed to use their build server to actually build your application. Since the code is open source, it is actually possible to build it yourself, but there were no build scripts available to automate this task, and the only instructions on how to do still required a fair bit of tinkering to get it to work.

Last month, as an exercise, I created an iOS port for CodenameOne that runs on Avian (a light-weight AOT compiler for Java), just to see if it was possible. It was indeed possible, and I was able to successfully get applications built with CodenameOne up and running using Avian on my iPhone. After some benchmarking, I found that there wasn’t a compelling performance difference between my Avian port and the XMLVM port that they are currently using on the build server. Therefore, rather than sink a lot of time into a competing port, it would be better to start working with the “official” XMLVM port for my development.

Today, as another exercise, I built an ANT target that would automate the building of a CodenameOne application for iOS on my local machine. To use it, you simply copy and paste the target into your Netbeans CodenameOne project’s build.xml, and modify some of the properties to point to the proper locations in my environment. Most of the logic is based on the build instructions that had previously posted in the CodenameOne forum.

Installation Prerequisites

You will need the following components to be in place on your system before you can use the ANT target:

After these are installed, the ANT target should work for any application you try to build.

Step 1: Checking out the CodenameOne repository

You simply need to open Terminal and check out the codename one repository. The following example creates a directory called “src” inside your home directory, and checks out codenameone in a directory named codenameone-read-only inside this src directory.

$ cd ~
$ mkdir src
$ cd src
$ svn checkout http://codenameone.googlecode.com/svn/trunk/ codenameone-read-only

At this point, the CodenameOne repository trunk will be located at ~/src/codenameone-read-only.

Step 2: Install XMLVM

The iOS Port project of the CodenameOne repository includes a copy of XMLVM that you can install if you don’t have it installed yet. It is located at:

codenameone-read-only/Ports/iOSPort/xmlvm

You can find installation instructions for XMLVM at http://xmlvm.org/documentation/

Update Dec. 14/2012: Currently you need to use the xmlvm distribution that is included inside the iOSPort directory. Installation instructions are still the same:
$ cd /path/to/codenameone-read-only/Ports/iOSPort/xmlvm
$ sudo ant
$ sudo ant install

The above instructions would install xmlvm at /usr/local/bin/xmlvm

Once you have XMLVM installed, you should be able to use the ANT target in your own projects.

Step 3: Add Build Scripts to iOSPort

The ANT target depends on a Python script to be able to add files to Xcode projects from the command line. You will need to download this buildscripts directory, and copy it into the codenameone-read-only/Ports/iOSPort directory (i.e. the final location would be

/path/to/codenameone-read-only/Ports/iOSPort/buildscripts

You can download these build scripts here

You also need to add a template for the Main application entry point into the iOSPort directory. Create a file at codenameone-read-only/Ports/iOSPort/MainStub.java with the following contents:

Adding the Ant Target to Your Project

  1. Create a CodenameOne application project in NetBeans (if you haven’t already).
  2. Open the build.xml file for your project. (e.g. you can click on the “Files” tab, then expand the tree node for your project, and double click the “build.xml” file.
  3. Paste the following snippet into the build.xml file. It can appear anywhere inside the <project>…</project> tags.
  4. Modify the codename1.repo.path property to point to the codenameone-read-only directory (i.e. where you checked out the CodenameOne repository to).
  5. Modify the xmlvm.path property to point to the XMLVM binary on your system.
  6. Modify the ant.path property to point to the ANT binary on your system.
  7. Modify the python.path property to point to the python binary on your system.

Building your Project in NetBeans

Once you have successfully added the the ANT target to your build.xml file, you should be able to build the project.

  1. Click on the “Files” tab.
  2. Right click on the “build.xml” file in your project, and select “Run Target” > “Other Targets” > “build-for-ios-device-locally”
  3. Wait. It should open Xcode with your project when it is finished building.
  4. You should be able to just run or build your project in Xcode like it is a normal iOS project. It will take some time (usually about 5 minutes per build), because XMLVM produces a couple thousand Objective-C files and includes them in the Xcode project. (Don’t worry, LLVM will strip out all unused code so that the resulting binary isn’t too big).

*Note: It doesn’t seem to like building for the simulator. You can only build for an iOS device currently. I believe this is because it includes a library, zbar, that is only compiled for arm devices (not the i386 emulator).

iOS Signing Identity & Provisioning Profile

It is worth noting that you will need to set up Xcode to use your iPhone Developer identity, or it will stop you in your tracks. You will also have to set up a provisioning profile if you are doing development builds. This was a real pain in the ** to get right (in fact it was probably harder than writing the ANT script), but there is lots of documentation on this on both the CodenameOne site and the Apple site (and all around Google too).

You’ll need to make sure that your App ID (set in Project Properties in NetBeans) will need to begin with your the unique code that your provisioning profile is set up with.

Current Limitations : Native Interfaces

This build script doesn’t currently build native interfaces that you may have developed as part of your application. Native Interfaces need to have some special glue generated at build time for them to work, and the code and specs for this glue have not been released. If you are using native interfaces, you’ll need to use the CodenameOne build server in order to access them.

I am working on replicating that glue so that Native interfaces will work in local builds, and will post it when complete. An inability to develop native interfaces locally is a major impediment to being able to contribute to the CodenameOne project. It is critical that *all* build functions can be performed locally or I fear that it will be difficult for a community to form around this wonderful project.

More Thoughts on Avian vs XMLVM for iOS

I’ve only been using CodenameOne for a couple of weeks now, and I’ve been experimenting with both Avian and XMLVM on iOS. As I mentioned above, the fact that XMLVM actually outperforms Avian on many benchmarks means that I may not pursue the Avian port much further. However there are a few aspects of using Avian that have come to my attention in the short time that I’ve been playing with CodenameOne:

  1. Debugging and Stack Traces are better on Avian. XMLVM currently isn’t a whole lot of help if you run across an exception. It states that stack traces are currently unavailable and simply prints the error message. Avian, on the other hand, will give you a full stack trace, which makes it easy to debug problems.
  2. A full Java runtime environment. In XMLVM there are a few things that don’t work the way you expect if you’re used to the Java runtime environment. E.g. I was trying to print debugging information to the console using the familiar System.out.println() only to find out that this doesn’t seem to output anything in XMLVM. (Not sure if there’s anything special I need to do to get this working). Also, things like loading resources from Jar files using Class.getResource() and Class.getResourceAsStream() don’t work on XMLVM. You need to use equivalents from the CodenameOne API which are thin wrappers over native methods that do the same thing.
  3. Well that’s all I have come up with so far..

Building Locally vs Sending to the CodenameOne build server

It is important for me to be able to build my CodenameOne projects locally because I want to start contributing to the project and I need to be able to test my changes to the CodenameOne core without sending them into Shai to add to the build server. However, for production releases, I still recommend using the build server. They have taken the time to sort of all of the kinks and add many optimizations that I just don’t have time to work out. Their build server is also a bit faster than building locally.

Avian vs XMLVM: AOT Java on iPhone Benchmarks

In my last post, I discussed the results of a benchmark comparison between XVMLVM and Avian both solving the Towers of Hanoi problem on an iPhone 4s. Originally it looked like XMLVM ran slightly faster, solving the problem in 35 seconds (vs 42 seconds for the Avian version).

The code that I used for the benchmark are as follows:

Codename One controller contains the actual benchmark timing code:

However, today I decided to try writing the same code directly in C using CodenameOne’s native interfaces. This way I would have a baseline with which to compare the performance – so that we know just how much performance we are giving up by using Java instead of C to write an iPhone App.

The native code for this benchmark is as follows:

And it was used in a CodenameOne controller to actually perform the benchmark timing as follows:

I was initially frustrated to find that the C version of my benchmark ran in 0 milliseconds (compared to about 35,000 ms for my Java version compiled with XMLVM/GCC and 42,000ms for my Java version compiled with Avian). Something had to be wrong. I checked to make sure that it was actually calling my function. It was indeed running the function. I tried increasing n to ridiculously large values (3000000), but it still ran in 0ms.

As it turns out the GCC/LLVM compiler was outsmarting my benchmark. Because the benchmark function didn’t return any values to to the caller, and didn’t affect any state outside of its local variables, it decided that the entire function could be replaced with No Op. This is sort of like a compiler’s version of “if a tree falls in the woods and nobody sees it…”. As far as GCC is concerned, the tree didn’t fall.

To solve this problem, I added a static variable that is incremented each time the function is called. This way the compiler wouldn’t be able to eliminate the code as dead. The revised C code looks like:

After modifying the benchmark to update a static variable (so that the compiler could no longer cheat), I was able to finally get a benchmark result. However, this discovery cast a shadow over my previous benchmark results, so I decided to modify the Java version to update a static variable (so that no cheating could take place).

The modified Java version looks like:

This time around, I found that Avian was marginally faster than XMLVM (about 15% faster).

The results of the revised benchmark are as follows:

Hand-coded C version (GCC/LLVM) 31.7 seconds
XMLVM version 65.8 seconds
Avian version 57.1 seconds

Changing to Use Object Methods Instead of Static Method Calls

After posting the above results in the XMLVM forum, Arno (the creator of XMLVM) suggested I try changing the TowerOfHanoi.move() method to not be static. I made the change as follows:

And the the actual benchmark timing code changed to:

Clearly, Arno had some insider knowledge about how the method dispatching works because this produced wildly different results for both XMLVM and Avian:

XMLVM version 40.2 seconds
Avian version 77.4 seconds

So XMLVM, in this test, narrows the gap between native C function calls, and its own method dispatching performance. (Less than 33% difference, which is negligible in the scheme of things). Avian clearly doesn’t handle object methods as quickly as it does static methods, and this really brings to a forefront Joel Dice’s comment that little benchmarks like this don’t really mean much. Applications do much more than perform recursive functions with simple integer arithmetic. The true performance of an application comes down to many factors including graphics, networking, memory allocation, floating point calculations, etc…

These experiments, for me, at least reaffirm that Java is a viable platform for developing for mobile. It should *not* suffer from the same performance problems that current HTML5 solutions do.

A Victory Lap for Java

The benchmarks above make it look like Java is at a disadvantage when compared to purely native apps written in Objective-C (even if in some tests XMLVM appears to have almost caught up). But these benchmarks are comparing to C function calls, which are very fast. What if we change the benchmark to use Objective-C messages. This, is not really fair, since it is well-known that Objective-C message passing is much slower than typical function and method dispatching. Nonetheless, let’s make try, if for no other reason than to know just *how* slow it is.

I changed the Native code as follows, so that it is using message calls for all recursive calls.

Not surprisingly, this benchmark ran much more slowly than the previous version:

Objective-C Message Calls 154.5 seconds

Thoughts in Summary

AOT-compiled Java (either by Avian or via XMLVM) produces performance that is comparable to native C code. It may actually perform better, but these benchmarks are very narrow in scope. The relative performance of XMLVM and Avian seem to vary widely depending on which operations are being performed. XMLVM seems to handle object methods very well, whereas Avian seemed to have slightly quicker dispatching of static methods.

In any case, I don’t have any reservations about the performance of CodenameOne in relation to native apps. Whether it uses XMLVM, Avian, or some other solution for deploying Java to iOS, it should be able to provide sufficient performance for any sort of application.

See Also

  1. CodenameOne + Avian = Java on iOS – My blog post discussing my experiment to create an Avian port for CodenameOne to run on iOS
  2. XMLVM is Actually Pretty Fast – My blog post discussing my initial benchmark results comparing Avian to XMLVM
  3. Codename One Avian Project on Github

XMLVM is Actually Pretty Fast

DISCLAIMER: The Benchmark results in this post turned out to be flawed due to GCC/LLVM optimizations unduly favouring XMLVM. Please see the next post where I discuss the corrected benchmark and associated results.

In a previous post, I described some of my experiments in creating an Avian port for CodeNameOne. As mentioned in the post, one of my motivations was to see if I could improve on the performance of the current default iOS port which uses XMLVM to convert the Java code into C code (and ultimately compiled with Xcode). I had a hunch that binaries produced via the XMLVM translation would be slower than an AOT compiled Java implementation because of the way it works (It converts VM byte code operations into C stack operations in the C language – which would presumably produce much less succinct code).

After some tedious conversion of XMLVM runtime library calls to JNI calls, I was able to successfully build my Avian iOS port for CodeNameOne. Next I created a simple application (based on the CodenameOne Tabbed Application template) that runs the Towers of Hanoi problem, and built two versions of the app:

  • One using the CodenameOne build server (which uses XMLVM in its build process)
  • – Another one using my Avian, Proguard, and Xcode.

The Benchmark Results

The results were surprising.

I ran both apps on my iPhone 4s which is on iOS 5. The app is set to solve the tower of Hanoi problem for n=30 moving from pole 1 to pole 3. The time required to complete the problem was pretty consistent. On average, the XMLVM app would complete the problem in 35 seconds, and the Avian app would complete it in 42 seconds.

NOTE: After fixing the benchmarks so that GCC/LLVM *had* to run all of the code, it turned out that Avian was actually a bit faster.

This is quite the *opposite* of what I expected. While I’m a little disappointed in the results, I am also encouraged. This means that the performance of apps developed in CodeNameOne for iOS (using their build server) is actually quite good. I can be confident that I am building on a solid foundation.

I posted these results on both the CodenameOne forum and the Avian forum and a few explanations for the outcome were proposed. One explanation, that makes sense is that the XMLVM build benefits from optimizations of GCC and LLVM such as method inlining, loop unrolling, autovectorization, code motion, and intelligent register allocation. Avian’s AOT compiler, being simpler, and far less mature doesn’t implement any of these optimizations so the resulting binary is actually working at a slight disadvantage.

Joel Dice (creator of Avian) did note that a simple benchmark like Towers of Hanoi is not really helpful for determining real-world performance. A full comparison on real-world tasks would be more informative.

UPDATE: The Benchmark results in this post turned out to be flawed due to GCC/LLVM optimizations unduly favouring XMLVM. Please see the next post where I discuss the corrected benchmark and associated results.

The Executable Size

Another important factor when producing a mobile app, is the actual executable size. Why install a 100MB application when you can get the same app in under a meg. I used Proguard on the Avian build to trim down the code size (so we don’t need to include the entire JRE. XMLVM, also uses a number of optimizations to ensure that dead code isn’t included in the final executable.

My test app came out at 3.5MB for the XMLVM build, and 6.0MB for the Avian build. So XMLVM seems to have won here again.

What Now For the Avian Port

Now that I have established that the current XMLVM implementation of the iOS port is quite fast indeed, there is little need to continue to develop an Avian port. This exercise was academic in nature, and I’m satisfied that I have achieved my goals, which were:

  1. Can it be done? (i.e. Create an Avian port for CodenameOne). The answer was YES!
  2. To learn about the CodenameOne architecture. I learned a lot.
  3. To learn about the Avian architecture. I learned a lot here too.
  4. Find out whether the performance would be dramatically improved by using an AOT java compiler instead of XMLVM -> C -> Xcode. The answer, for now, was NO. XMLVM is pretty fast as it is.

Despite that fact that my experiment didn’t yield any performance improvements, there still might be some advantages to developing apps on the Avian stack. Off the top of my head, these include:

  1. A more familiar Java environment. JNI instead of XMLVM’s runtime when interacting with the native environment.
  2. JDK7 support. I’m not actually sure what version of Java I could use with CodenameOne’s XMLVM implementation. It is at least Java 5, but I don’t think it is at Java 7. I notice that they use Apache Harmony for the iOS port.
  3. Perhaps better debugging and exception handling. Shai Almog noted that XMLVM doesn’t support ClassCastException and doesn’t check cast validity. Its stack traces are also a bit cryptic when you get an exception.

Up Next For Avian/iOS

I am keen to try my next experiment with Avian and iOS: Combining my Java-Objective-C bridge with Avian to produce a Java solution that is similar to MonoTouch. I.e. Where you write the code in Java but still use the Apple development tools for the UI. This wouldn’t be a cross-platform solution like CodenameOne produces, but it would be useful, I think.

Up Next for CodenameOne

Time to develop some real-world apps!

7A942R3ZJ88P

Apple’s Walled Prison

I endure it because they make great software. I endure it because I have become dependent on their ecosystem. I endure it because there’s money in developing software for their platform.

But I am ever so close to just saying “Forget it” and moving on.

Apple’s simplistic DRM solutions for iPhone reduce the utility of the device by about 90%. They don’t even seem to consider what happens when you have 2 or 3 people in a family, all with separate iPhones all synced to the same computer. They don’t seem to care about people who have a desktop and a laptop computer and need to be able to copy files and apps to their phone from either of these devices.

Just a glimpse of my life with Apple’s walled prison last night. I was developing some sample Apps using CodeNameOne, NetBeans and Xcode. I have the full dev environment on my laptop, but my iPhone happens to be paired with my Desktop. When it comes time to “test” out my app on MY phone, I need to first register my phone with Apple as a development device, then set up and install a provisioning profile onto the phone. This part was about an hour of mucking around that I would like to have back.

Then it comes to copying my test app to my phone. Of course, I can’t do that from my laptop. I need to kick my wife off the desktop computer so that I can first copy the app to the desktop computer. From there I should be able to copy the app to my phone with no problems, right? Well not so fast. Apple is a firm believer in Murphy’s law, and a simple “copy” just wouldn’t cut it.

First attempt it tells me that my phone is not authorized for the apps on this computer, so i would need to erase my entire phone to continue. I discovered that iTunes was signed into the iTunes store under my wife’s account – which was the source of the problem.

After logging out of the iTunes store and logging back in with my account, I make another attempt. At this point it stopped pushing me to erase my entire phone, but it seemed to be complaining that several apps were not authorized for this computer. E.g. My Gmail app and my Netflix app. I guess I installed them straight from the App store. It prompted me to authorize them, at which point I entered my iTunes username and password. It took the password and then informed me that the apps still weren’t authorized. 4 or 5 times around this circle, I finally decided to just go with the “Don’t Authorize” button. After all, my goal here is to simply copy ONE test app that I had written onto my iPhone.

After opting to “not authorize” my apps I was informed that I would be required to delete the apps. At this point I just wanted to proceed so I said “fine, delete them!”.

After that I was able to copy my test app onto the phone and it ran quite nicely.

So at the end of the day, my test app written with CodenameOne runs great, and the number of installed apps on my phone has been reduced by 25%. No gmail, No netflix…. I guess I’ll just have to install them again and go through this dance once more.

This is not an isolated incident. Just the most recent in my lifetime of troubled interaction with my iDevices. In the past I have given up on such difficult tasks as
1. Copying a video from my computer to my iPad.
2. Copying a song from my computer to my iPhone
3. Copying a PDF from my computer to my iPad.

Up until now, I had solved the problem by just reducing the number of things that I do with these devices. I was down to just checking email. But since the Apple gods have deemed my unauthorized to use my Gmail app, I guess I won’t be doing that either.

CodeNameOne + Avian = Java on iOS

In my last blog post I was expressing my hopes for a Write-Once-Run-Anywhere solution for Java mobile. One of the founders of CodeNameOne responded to the post by saying that CodeNameOne offered everything that I was looking for. It provides a full solution for writing mobile apps in Java that will run in iOS, Blackberry, Android, and J2ME. They provide a Java class library that encapsulates most useful functionality required by a mobile app (e.g. GUI toolkit, Contacts, Camera, Location, Database, Network, Video, Web Browser, etc…). Their GUI solution is akin to Swing in that it is light-weight and pluggable – making it ideal for cross-platform development.

I was already aware of CodeNameOne and had it at the top of my list to try out. A few months ago, I downloaded their Netbeans plugin and played with it a bit – though my “playing” was limited to just starting a new project from a template and trying out their build server to see what the finished iOS executable looked like. I was actually quite impressed that the app (a simple 4 tab application with a few buttons and a map) came out at a trim 6 megabytes. For java this is good, because this had to include all of the components from the JRE compiled into the binary.

My main stumbling block was the dependence on their build server for actually producing the distributable application. The build server, from my brief interaction with it, works flawlessly, but I don’t like making myself too dependent on factors beyond my control. I have been burned already several times by “the cloud”. I have written software that relies on cloud APIs that are backed by major players like Google. In every case, the API has either been discontinued at some later date, or has been changed to a pay-per-use API that renders the application unusable. As another example, when the iPad first came out I purchased some comics through an app that was based on “the cloud”. I stopped using the app for a year, and when I went to use it again, the company had changed to a 3rd party provider for their purchasing – and all of the comics I had purchased no longer “worked”. Similar things have happened in the Mac App store due to changes in policies.

In any case, I am no longer naive (and may be a bit jaded) when it comes to building a process that relies heavily on “the cloud”.

With these “cloudy” experiences as a backdrop, the ability to build my own applications (at least as an option) is very important to me. In navigating around the CodeNameOne site (when I was first investigating it), I was not able to find any instructions on how to build the applications myself. A few questions had been asked in the forum but the response was that, while it is possible to build it yourself, the weren’t supporting it because it was complex and they didn’t want to clog up the support forum with requests of this nature.

Thankfully, I was finally able to find some instructions in the forum on how to build a CodenameOne application using XMLVM. This thanks to jon…@gmail.com for posting these. They were a lifesaver.

The Avian Port

I also mentioned in my last blog post that Avian had great potential for bringing Java to iOS since it is a lightweight JVM that provides AOT compilation. Its creator, Joel Dice, has already posted a simple “Hello World” application that runs on iOS using Avian. This provides a solid foundation for further development, and importantly a starting point for writing an Avian port for CodeNameOne

Let’s back up a little….

Why would I want to write an Avian port for CodeNameOne? Didn’t I just say that CodeNameOne already provides the ability to deploy Java apps on iOS?

My motivations for writing an Avian port for CodenameOne are three fold:

  1. To get intimately acquainted with the CodeNameOne architecture so that I can become a productive developer on the platform.
  2. The get familiar with Avian so that I can make use of it in my future projects.
  3. To see if I can improve the performance. UPDATE: Check out my later blog post where I discuss my benchmark results

The performance issue is of abstract importance to me at this time. If performance didn’t matter at all, I would just use a stack like PhoneGap to create multi-platform apps. But performance matters, you you *can* tell the difference between a native app and a PhoneGap app when it comes to things like scrolling. Writing games and heavily graphical applications also depend greatly on performance. Especially when we’re talking about low-powered mobile devices like the iPhone.

CodeNameOne’s iOS implementation is currently based on XMLVM, which is a brilliant project developed and maintained by Arno Puder. It works by converting the primitive virtual machine instructions into an intermediate XML representation, which can then be transformed into another language. E.g. The JVM is a stack based virtual machine, so many of the instructions just boil down to stack operations. These can quite easily be represented in any programming language. In XMLVM’s case it is converting the Java VM instructions into C source code.

If you actually go through the build steps for XMLVM, you can take a look at the C code that is generated. Basically a C source file corresponding to each Java library that is used in the application, is produced. It uses name mangling to produce functions that correspond to each Java method, and it provides a small set of runtime functions to be able to interact with the generated code (e.g. convert data types).

I think this solution is particularly clever. It gives us an excellent baseline for porting from one language to another. My instinct tells me, though, that the performance probably takes a bit of a hit due to the increase in number of commands required to perform each function. I haven’t done any benchmarks to test out this theory, but Shai Almog did acknowledge this during the JavaOne demo. (UPDATE: Check out my later blog post where I discuss my benchmark results). He did say that many of the important native iOS functions have been hand-coded, though so performance is pretty good where it counts.

Avian, on the other hand, compiles Java down to machine code so it should be very fast. I suspect, almost as fast or even faster than Objective-C for some things. I would like to be able to compare the performance, side-by-side, with the XMLVM implementation so that I can find out how much of an improvement there is to be gained. Realistically, if we want to treat CodeNameOne as a platform on which we can build a vibrant ecosystem of applications, plugins, and libraries, then the foundation needs to be as *fast* and *solid* as possible. UPDATE: Check out my later blog post where I discuss my benchmark results

Creating the Avian Port

In order to create the Avian port, I just needed three puzzle pieces to fall into place:

  1. I needed to see a sample of a project that can be built and run on iOS. The hello-ios sample project posted by Joel Dice, contains enough detail to work with in this area.
  2. I needed to see how the existing XMLVM port is built. Thanks to Shai Almog for pointing me to this post that describes the steps..
  3. I needed to know a little bit about the CodeNameOne architecture. Specifically where it interfaces with the native environment. Thanks, again, to Shai Almog for giving me some pointers in this area. It turns out that most of the native interface is contained in a single class: com.codename1impl.ios.IOSNative. Its native implementations were likewise contained inside a single IOSNative.m file which can quite easily (though tediously) adapted to use JNI instead of XMLVM.

With these 3 pieces in place, it was just a matter of time, sweat, and carpel tunnel syndrome to make the Avian port a reality.

The CodeNameOne Architecture & The iOSPort Project

If you want to start hacking on the CodeNameOne core, the best place to start, is with the code. You can check out the entire repository, which includes the foundation libraries, the designer project, and all of the port sub-projects. These instructions almost worked perfectly for me, except that there were some problems compiling the bar-code reader libraries, which likely are a new feature since the instructions had been written. I didn’t actually get it to build completely, but I got close enough that I’m sure I could have without too much extra work.

The iOSPort project includes a blueprint that can be quite easily followed to port CodenameOne to any platform you desire. All platform specific functionality is provided by a single class, CodenameOneImplementation, which can be overridden as necessary to implement functionality for the platform. The iOSPort project further factors out most native methods into the iOSNative class. This native class uses XMLVM conventions for native classes rather than the more common JNI conventions, but it was easy enough to generate JNI headers for this class and port all of the functionality over.

With the XMLVM-powered port, all of the source code in CodeNameOne, Apache Harmony, the iOSPort project, and the actual mobile app that is to be built is converted to Objective-C code using the XMLVM compiler. This produces a rather large project since .h and .m files are generated which correspond to each Java class that is used. A set of hand-coded native sources (Objective-C) in the nativeSources directory of the iOSPort project are also included. These one of these Objective-C source files is IOSNative.m, which includes all of the native implementations for the IOSNative class, but there are also several other classes that encapsulate various other components, and are referenced by IOSNative.m.

In producing an Avian version, I primarily just had to go through each of these hand-coded native files and replace all references to XMLVM with corresponding functionality that makes use of the JNI functions. Most of the references to XMLVM involved type conversion and array manipulation, which XMLVM provides some runtime convenience methods for. These replacements were tedious but not terribly difficult. After all of the replacements were made, it was just a matter of adding all of the source files to an Xcode project that is set up to build using Avian, then dealing with build errors one at a time.

The iOSPortAvian Project

Once I replaced all of the XMLVM references with JNI equivalents, I was able to set up an Xcode project scaffold based on the Hello-IOS example. The process for setting up the Xcode project was roughly as follows:

  1. Download the OpenJDK Mac port files from SVN. Download Avian from SVN. Download Proguard. Download the Hello-ios Project.
  2. Add all files in the iOSPortAvian/nativeSources directory to the Xcode project.
  3. Build the JDK.
  4. Copy all of the Java source files and resource files that are found in the CodeNameOne project and in the application to be built into the src directory of the Hello-IOS project.
  5. Use a modified make file to build the Java source code into native binaries and link them into the Xcode project.
  6. Create a custom entry point for the application, main.m, that initializes the JVM using JNI and passes control to the CodenameOne_GLAppDelegate class to enter the application.

Most of the build steps have been included in the build.xml ANT task that is part of the iOSPortAvian project.

I have uploaded the entire project source on GitHub as a point of reference for others who may want to extend it or learn from it.

I will write the specific steps required to build your app with Avian in a future blog post.

The KitchenSink Demo App Running on Avian

My first test app was just the “Hello World” app that is produced from the CodeNameOne template in Netbeans. The next one was the Kitchen Sink demo app. Most of the app started up with no problems. Yay!! Themes worked. Effects and transitions worked. As a proof of concept this feels very close to viable.

>Problems with Garbage Collection

Unfortunately I hit a snag that I suspect is related to Avian’s garbage collection. After performing a few successful transitions and functions, the Kitchen Sink app would crash with an EXC_BAD_ACCESS error (using the iOS simulator). I suspect this problem is related to Avian’s garbage collection but I don’t really have any leads on how to solve this issue. I have posted the issue in the Avian forum but haven’t had any response yet. Until such time as I have a lead in this area, the Avian port will remain 99% complete – but unusable.

UPDATE: Thanks to Joel Dice in suggesting some debugging techniques, I was able to solve the garbage collection issue. It is now working 100%!!

Thoughts in Summary

  1. CodenameOne is the real deal. It really does provide cross-platform mobile development in Java. I really hope the community gets behind this project because it is worth of attention.
  2. The CodenameOne devs (Shai Almog, and Chen Fishbein) deserve medals for their work on this project. The massive scope of the project across so many platforms surely required a massive effort to get it working. If you look at the CodeNameOne forums you’ll see that Shai responds to pretty much every inquiry that comes in the same day in most cases. If you look at the source code of the project, you’ll see their names in pretty much every javadoc, which tells me that these guys are wearing both the tech support hats and the dev hats for this project. I really hope a community forms that takes some of the burden off of these founders. Being the maintainer of some other open source projects myself, I know how difficult it can be when you have to respond to every question that comes into the forum.
  3. Avian is very cool also, but the community doesn’t seem to be there. I have posted 4 questions to the forum and have not received a response to any of them. I answered my own queries in the forum when I found the answers myself, but the last query that is currently the show stopper, hasn’t received a response yet. Since Avian is the only pure AOT solution that I’m aware of that has working examples on the iOS, I think it is still work paying attention to even if the community isn’t really there yet.
  4. XMLVM is brilliant. A great way to learn about the possibilities of XMLVM is to look at the iOSPort project of CodeNameOne. It is a wonderful example of the possibilities. I didn’t actually get to the point where I could compare the performance with Avian/Native code, but the fact that it is being used successfully in CodenameOne serves as a compelling proof of concept for it. Great work, Arno and team on this.
  5. I still don’t have a good handle on the relative benefits of using CodeNameOne vs using an HTML5 technology (e.g. PhoneGap) vs using Native (other than the fact that Java is a superior language, IMHO). Does CodeNameOne’s performance rival native apps? Does it beat the performance of HTML5 apps? If so, what tangible things can be achieved with CodeNameOne that cannot be done with HTML5?
  6. Currently CodeNameOne doesn’t support external Jar files. This is partly because it doesn’t support the full J2SE spec for all platforms. You can work around this problem by just adding the source files for the external libraries into your application’s project. However this kind of nullifies one of the best features of Java: the ability to build up collections of third party libraries that can be used in multiple projects. I suspect that this feature will be added in future releases, but it is certainly a notable omission for now.
  7. All of this tinkering with building my CodeNameOne projects on my own are merely academic for now. Even if I did produce a working Avian port, I would probably still opt to use their build server since it is so automatic and they have worked out all of the little issues with optimization. That said, I think without easily accessible public build instructions, it will be difficult for an open source community to build up.
  8. I still want JavaFX on mobile. I haven’t really explored the limits of the UI and graphical API capabilities of the CodeNameOne libraries, but I can guarantee that they don’t come close to approaching the capabilities of JavaFX.

Follow Up

Check out my later article where I discuss the results of a benchmark comparing the performance of XMLVM and Avian.

I want Java on Mobile

What makes Java unique? Actually there are quite a few things that set it apart from other languages, but I want to focus on its true cross-platform presence. No other platform provides the end-to-end tools for building a robust desktop application and deploying it on every major desktop operating system. The best you can hope for with other languages is that you can share most of your business logic across platforms, but when it comes to the user interface, well, you need to build that separately for each platform.

The mobile space, sadly, is a different story. Many devices do use JavaME, but the big players (Android, iOS, Windows Phone, Blackberry) all have their own toolkits that make it difficult to truly write once run anywhere. While Android and Blackberry do use Java as their primary development language, their toolkits are incompatible with each other. iOS and Windows Phone, likewise, are incompatible with each other, and everyone else. What I want is a Java toolkit that does for mobile what Swing (and now JavaFX) did for desktop.

2012 has seen some progress where there was previously only darkness. There are now a handful of solutions that will allow you to write mobile apps with Java (e.g. CodeNameOne, ADF Mobile, J2Objc, Avian, to name a few), but none of these offer the same type of run-once-run-anywhere development experience as Swing did (and JavaFX does now). CodeNameOne, perhaps, comes the closest, as they provide cross-platform libraries for most things, including the UI. My hesitation with this framework is its dependence on their cloud services for building the applications. ADF Mobile includes a small JVM for the business logic, but relies on PhoneGAP (HTML5) for the user interface and for interacting with Phone services. J2Obj is interesting also, as it allows you to compile Java source code to Objective-C code that can be used from your iOS front-end, but this doesn’t get us anywhere near cross-platform development – just easier sharing of code between Android and iOS. Avian, is an alternative, light-weight JVM that provides AOT compilation and has been successfully used to build ARM binaries that can be run on iOS. It provides, perhaps, perhaps the most hope since it is open source. But examples are scarce for iOS, and it isn’t backed by any major players at this time AFAIK.

There seem to be two trends for attacking cross-platform mobile development:

  1. Write Once, Run Anywhere – Using HTML5 for the UI.
  2. Share business logic, but use native tools for building and designing the UI.

The problem with the first approach is mostly performance related. HTML5 is great, but on mobile devices you may need to crank as much as you can out of that little processor. The second option solve the performance issue, but it just isn’t as fun. Nor is it as maintainable.

I want what is behind door number 3: Write once, run anywhere, with a rich UI toolkit that is cross-platform but has a pluggable look and feel so that the applications can be made to look native. This UI toolkit should be efficient (perhaps OpenGL) so that we aren’t having to choose between portability and performance to a great degree.

I guess, what I want is JavaFX on mobile (i.e. iOS, Blackberry, Android, and Windows Phone).

PDF Table of Contents with Docbook & FOP

This post is, more or less, a note to self so that I can look up how to do this later on. I use docbook to write documentation for some of my projects and I have a set of shell scripts set up to render the docs as HTML and PDF. I use Xalan as my XSLT processor. Every once in a while I find myself wanting to change some aspect of the output. E.g. changing the heading styles in the HTML output, or adjusting the number of levels of section headings that will appear in the table of contents.

Today I decided that I wanted my PDFs to be generated with those handy bookmarks in the left margin of the page so that I could more easily navigate to the various parts of the manual.

I found most of my answer here. All I had to do was enable fop extensions when running XALAN. Here is the shell script that I have patched together over time to run Xalan with all of my preferred XSLT settings:

Note that this source uses fop1.extensions 1 rather than fop.extensions 1 as recommended in aforementioned article. This is because fop.extensions activates a namespace for FOP extensions that was in use prior to version 0.9. If you are using 1.0 or higher (as I apparently am), you need to specify fop1.extensions or you’ll get a nasty exception stack trace like this:

Thanks to this thread for pointing this out.

If you’re not using Docbook to write your manuals, then you owe it to yourself to look into it. It took me a month of Sundays to get my setup just right, but it was worth it.

After this modification, I have my beautiful PDF with a bookmarked table of contents:

Generalized PHP Caching Solution

I recently became responsible for maintaining service level of a Joomla! website. The
site is hosted on a CentOS VPS instance with NGINX and PHP running with FastCGI. The site had been previously hosted on a shared server, but was forced to upgrade to a VPS when the load expanded.

Unfortunately, even on the VPS, the site was getting crushed by traffic. It was taking upwards of 10 seconds to render a page through Joomla!, and the site wasn’t even under *that* heavy of a load (approx 1200 unique visitors per day). I don’t know if there is something wrong with the Joomla instance or if the server has actually just reached the limit of what it can handle.

Obviously 10 seconds to render a page is unacceptable, so this problem needed to be solved one way or another. Faced with a *live* website that needed to have performance fixed asap (like yesterday) I didn’t have the luxury of experimenting with configuration variables in Nginx and just hoping. I needed to do something quickly that would have a high probability of success.

I chose to write a generalized page cache in PHP.

When implementing a caching strategy you really need to be aware of how the site works so that you can be sure that you’re not breaking things. Luckily, this site is pretty static. Only a few select people need to log in and add content. The rest of the public just needs to view the content. This is a good situation, because it means I don’t have to fiddle with a separate cache for every user. I could use the cache for the public, and skip the cache for users who are logged in (or trying to log in).

Note that there are a number of plugins available for Joomla that might help improve performance, but, not being a Joomla expert, I decided to treat Joomla as a black box, and implement the cache in front of Joomla. All that was necessary was to add small hook to the beginning of the index.php file that checks the file-system cache for a cached version of the currently requested page. If the page is there, then we return the page and stop execution without even loading Joomla. If the page is not there, then we register a shutdown hook and allow the request to continue to Joomla. At the end of the request, the shutdown hook will run and save the generated page to the cache, as well as outputting it to the client.

The code goes roughly as follows:

The call to ob_start() causes PHP to write all output to a buffer rather than to the client. When script execution completes, it will pass this buffered content to the flushBuffer() function, that we define. This flushBuffer() function is responsible for saving the content to the cache so that next time it can be retrieved there.

Now, let’s look at some of the secret sauce inside the checkCache() and flushBuffer() functions.

checkCache() would look something like:

My actual code includes quite a few more options than this to account for whether the user is logged in and maintaining certain headers in the cache, but this gives you an idea of the workflow.

The flushBuffer() function would look something like:

All this does is saves the buffered content to a file in the filesystem, and returns
the buffer contents so that they will be displayed to the user.

Just this tiny addition helps the server load dramatically. It will buy us some time to refine the caching strategy further.

Some small additions that you’ll likely want to make to this setup include:

  1. Allow a particular header or cookie to refresh a page on demand.
  2. Skip the cache if the user is accessing a login page or is already logged.
  3. Save certain headers of the original request, and pass them back in the cache. (Note: you should not retain cookies and other headers that could contain confidential information.. Just content-type, and other stateless headers).
  4. Adjust the expiry time as appropriate for your setup.

Unfortunately our site still has a problem. We can’t increase the expiry time any longer than 24 hours because information is being refreshed to frequently, and one change can potentially update any page in the site. This combined with the fact that there are thousands of articles on our site, means that there is a hight likelihood of cache misses. If the site is being crawled by a couple of search engines, it is still very likely that the Joomla would have to handle multiple simultaneous requests – and this could still crush the server.

One solution, whose implementation I’ll describe in the next article, is to not refresh the cache immediately when an expired page is requested, but rather to just return the expired page to the client, and queue the page for refresh. Then have a daemon run in the background to refresh one page at a time, based on the refresh queue. This will ensure that Joomla is never overloaded.