Category Archives: Software Development

Posts about software development. Generally I use Java, PHP, and Python for development but occasionally I delve into other things as well.

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.

Speaking Cocoa From Java

Java on the Mac recently got a major boost to its profile as a platform for building Mac software when JavaFX ensemble was accepted into the App Store. This was not the first Java app to make it into the app store, but it was the first that used JavaFX. Having recently attended a number of talks on JavaFX at JavaOne, I can tell you that it is really something to get excited about, especially if you are a Java developer. The combination of its fast, rich graphics and media support with a first-rate visual GUI builder (JavaFX Scenebuilder) make for a platform on which you can be both productive and creative.

So let’s get busy writing Mac software in JavaFX. Well….. not so fast. In order to comply with App store guidelines, and to provide a native user-interface experience for Mac users, you still need to be able to talk to some native frameworks.

One major problem is that JFileChooser is not compatible with the Mac App Store because it doesn’t work inside the App Sandbox. The current recommended approach is to use the old java.awt.FileDialog class, but this has some serious limitations. For example, if your user enters a file name with an incorrect extension for your purposes, you are not allowed to programmatically fix it, and the FileDialog doesn’t include any features to force a certain file extension. In cases like this it would be really nice to just be able to use the native NSSavePanel class to show a modal save dialog without having to jump through too many hoops. In a previous post, I described how to use JNI to build a Java wrapper around NSSavePanel, and this is a viable way to go, but this is quite a lot of hassle to just be able to use a simple file dialog.

The NSSavePanel example is only the tip of the iceberg. When you start looking through the Mac OS X frameworks, it becomes clear that there are a lot of fun toys to play with, and a few other essentials that you cannot live without. (E.g. if you want to allow in-app purchase, you’ll need to be able to interact with the StoreKit framework).

Do we really have to battle with JNI, every time we want to make a call to an Objective-C library? Luckily, the answer is no. We do have some easier options. The Rococoa framework is an open source successor to Apple’s discontinued Java-Cocoa bridge. It sits atop JNA and provides access to some core Mac OS X frameworks by way of generated Java class stubs. JDK7 and JDK8 have a little documented library called JObjC included with it, that also provides the core OS X frameworks as generated Java class stubs. Unfortunately, both of these libraries suffer from a serious lack of documentation. In the Rococoa case, there is some documentation, but most of it was written in 2005 and much of it no longer works. JObjC doesn’t seem to have any documentation to speak of aside from the unit tests (It doesn’t even include any javadoc comments).

The biggest pitfall of both of these libraries (in my opinion), is that they rely on you to build class stubs for the frameworks that you require. There are build scripts for this (e.g. JNAerator for Rococoa and JObjC has its own Ruby script that generates class stubs using the OS X bridge support XML files), but they don’t work out of the box. And frankly, after spending 3 days fighting with JNAerator and not getting it to successfully build any stubs, I’m not even sure it the current version even works. The trouble with having to run build scripts is that you need to have your build environment set up just right for them to work. If you reach a point in developing a Java application where you just want to call native method, or access a native framework, you don’t really want to have to go and build an entire mess of class structures from source. Or maybe that’s just me.

So then what? Is there a simpler option? Not that I could find. So I built one myself.

Some background on me: I am primarily a Java developer, but I have read numerous books on Objective-C and Cocoa with the anticipation that, some day, I might actually get around to writing a Cocoa App. I, therefore, prefer to write more code in Java and less in Objective-C, but I’m quite familiar with how the Objective-C runtime works and what the Cocoa frameworks have to offer.

One nice thing about Objective-C is that it has a dynamic runtime that you can easily interact with by way of just a few C functions. It provides a means of passing messages
to objects. This is the entire basis for the “Objective” part of Objective-C. JNA is a fantastic library that allows us to call C functions directly from Java. Therefore, using JNA we can interact with the Objective-C runtime via its C API.

When it comes right down to it, all I really need is a few functions:

  1. objc_msgSend(), to pass messages to objects.
  2. objc_getClass(), to get a pointer to a class.
  3. selector_getUid(), to get the pointer to a selector.

And there are a few other useful functions, but I won’t mention them here. The first thing I needed to find out was how an Objective-C object looked inside of Java (using the JNA API). As it turns out, an Objective-C object can be simply represented by its address as a long variable. JNA provides a useful wrapper class, com.sun.jna.Pointer around an address that can be used interchangeably in your JNA method wrappers.

With just this tiny piece of information, you can start to see what would be required to build a generalized wrapper for Objective-C from Java. By obtaining a pointer to a class via the objc_getClass() function and a selector via the selector_getUid() function, you can create an instance of any class by passing the selector to the class via the objc_msgSend() function.

You can then pass messages to the resulting object using the objc_msgSend() function again.

This is almost enough to form the foundation of a one-way, working bridge. But there are, of course a few caveats.

For example the objc_msgSend() only works for messages that have simple return types (e.g. Pointers, ints, etc..). If it returns a structure, then you need to use the objc_msgSend_sret() function, and messages that return a double or float value need to be sent with the objc_msgSend_fret() function.

But, for the most part, this understanding is sufficient for creating a one-way bridge.

After a little JNA magic, we have a simple, low-level API for sending messages to the Objective-C runtime. The following snippet is from a unit test that is testing out this low-level API:

However exciting it may be to be able to send messages to Objective-C objects, this level of abstraction is still too low to be “fun”. So I built a little bit of abstraction over top of this layer to, for example, allow sending messages without having to first look up the class and selector.

The following is a snippet from another unit test that is sending messages at a slightly higher level of abstraction:

And this can be improved even more:

At this point, we can quite easily interact with Cocoa without too much pain. But we still aren’t quite at the level of abstraction that we like. The next step would be to build an object-oriented wrapper around the Objective-C objects so that we’re not dealing directly with Pointers and long addresses to objects.

For this, I created the Client and Proxy classes. The Client class is an singleton class that allows you to interact with the Objective-C runtime. It allows you to send messages to objects, and it provides automatic type mapping for both inputs and outputs so that the correct message function is used. E.g. using Objective-C Type codings for messages, it determines the return type and input argument types of the messages so that the correct variant of objc_msgSend() is used and that the output is in a format of our liking.

Objective-C objects are automatically converted to and from Proxy objects
(which are just wrappers around the Objective-C object pointers). NSString objects are automatically converted to and from Java Strings. It also introduces a set of
methods for sending messages that expect a certain return type. E.g. The sendInt() method is for sending messages that return ints, and sendString() method is for sending messages that return Strings.

The Proxy class is a thin wrapper around an objective-C object. It uses a Client instance to actually send the messages, and it provides wrappers around all of the relevant send() methods.

The following is some sample code that interacts with the Objective-C Runtime at this slightly higher level of abstraction:

At this level of abstraction, it is pretty easy to add little bits of Cocoa functionality into our Java application. But there is one Major thing missing: Objective-C to Java communication. This is critical if you want to be able to write delegate classes in Java that can be passed to Objective-C objects to handle some callbacks.

Calling Java From Objective-C

One-way communication will get you only so far. If you need to pass a callback to an Objective-C message, or write a delegate class in Java that can be called from Objective-C, we’ll need full two-way communication.

There are a few ways to accomplish this, but I chose to make use of the NSProxy and a little bit of JNI to create an Objective-C object that acts as a proxy to a Java object. Whereas our Proxy Java class that we defined before contained a one-way link to its native peer object, the NSProxy subclass will provide its own one-way link to its Java peer. Combining these two strategies, we end up with a two-way bridge between Java and Objective-C, such that we can call Java methods from Objective-C, and Objective-C methods from Java.

I’ll go into detail on how this was achieved in a future post, but for now I’ll give an example of how the resulting API looks from the Java side of things.

The following is a sample application that opens the NSOpenPanel dialog and registers itself (a Java class, which is a subclass of the NSObject Java class) as a delegate for the dialog.

We introduced a special annoation @Msg to mark Java methods that should be accessible as Objective-C messages. This allows us to specify the selector and signature for the message in a way that the Objective-C runtime understands. Notice that we can even use the Proxy.send() method to send messages to our Java class. This actually sends the message to the Objective-C runtime, which pipes it back to the Java class to be handled — and if the Java class doesn’t define a method to handle the message, it will pipe it back to Objective-C to be handled by the superclass.

To find out more and download the library…

You can download the source or binaries for this project on Github. I have also posted the Javadocs here.

Scrolling iFrame on iOS

I just finished adding scrolling support to the RecordDialog class in Xataface for the iPad. The RecordDialog basically allows you to open an edit form or new record form in an iframe using a Javascript call. This is useful if you want to be able to pop up a form without the user having to navigate away from the page. It uses an iFrame for legacy reasons, until the forms API can be updated to work 100% through AJAX. This component has worked well for a long time on the desktop, and it works okay on the iPad and iPhone if the form fits inside the iframe without having to scroll. The trouble is that you can’t scroll an iframe on iOS, so if the form is too long, it just gets cut off and the user can’t see the bottom of the form.

After some Google searching I found a few strategies for overcoming this issue. The proposed solutions can be categorized into 3 groups, and all of the solutions have one common element: start by making the iframe unscrollable using the scrolling=”no” HTML attribute. From there, you can either:

  1. Set the iframe height to be as tall as the document body, and wrap the iframe in a scrollable div tag.
  2. Wrap the contents of the iframe in a scrollable div tag. (This requires sizing the DIV’s height to be the same as the iframe’s parent’s inner height).
  3. Use javascript touchStart and touchMove events to do scrolling with Javascript inside the iframe.

After experimenting with options #1 and #3, I settled on solution #2: wrapping the iframe’s contents because it seems to work best for all occasions. Of course this solution won’t work if you don’t own the contents of the iframe.

Option #1 (wrapping the iframe in a scrollable div) is problematic because, by changing the size of the iframe to be taller than the screen, potentially, it screws up calculations in the body of the iframe that rely on window height. I found that dialogs that are created to be displayed in the middle of the page end up displaying way down the page because the window is deemed to be effectively the size of the iframe, which has been artificially resized to be way too big.

Option #3 didn’t look as appealing because of the amount of custom javascript handling. I just have the feeling that I would have been starting down a long road of browser incompatibility glitches.

Resources

  • A good blog post on some of these strategies
  • A stack overflow conversation on the topic.
  • OS X JNI Tutorial

    I have just recently completed my first JNI library for use with one of my applications. Since I have found documentation on JNI (especially on Mac OS X) to be sparse, I decided to write a tutorial about the process so that others can learn from some of the mistakes I made. I wrote the tutorial using Docbook. See the links below to view the tutorial.

    HTML Version

    PDF Version

    Feedback welcome.

    JavaOne: A Look Back

    I am now home from my Bay area adventure at Java One. This was the first conference I’ve attended since 2005, and is by far the largest conference I’ve ever been a part of. I was blown away by the scale of this one. The downtown core was plastered with Oracle and Java signs. Buses dipped in oracle insignias roamed the streets constantly, and you couldn’t walk a block without seeing at least 5 people brandishing Oracle swag. (I quite liked the back pack that they provided).

    In addition to the sessions (which I’ll get to next), there was a steady stream of entertainment events for the benefit of conference attendees. Union square (and a few other locations) were blocked off for music performances; and then there was the “fan appreciation” event featuring Pearl Jam and Kings of Leon. Doesn’t sound like nerd conference, does it?

    The Sessions

    My reason for attending was the sessions. From Sunday to Thursday my schedule was jam packed with talks about topics ranging from JavaFX to MongoDB and a smattering of Java ME, iOS, and Android development. For any given one hour slot, I had to choose between 2 or 3 talks that I really wanted to see, and another 8 or 9 that would have been interesting. Being able to hear about new technologies directly from the people who are behind it is awesome. It imparts a kind of understanding that cannot be achieved through a book or reading blog posts.

    This conference has sparked a fire in me to seek out more conferences like this, similar to the way that a my first exposure to Disneyland led me to look for other parks that offer the same experience. In fact, the way a child reacts to his first experience at Disneyland is an accurate way to describe my reaction to the conference schedule.

    The Topics

    Currently I have a number of desktop applications that have been developed in Swing and have been deployed as applications on OS X. Therefore, I was most interested in learning about Swing’s successor, JavaFX, and how to deploy applications on OS X. The conference was heavy on JavaFX (yay!) but a little light on OS X. There were two talks on OS X deployment, but sadly I could only attend the first one (which way a fantastic talk, by Scott Kovatch). Nonetheless, I have left the conference with stockpiles of new ammunition for building applications with JavaFX. In fact, I’m really exciting about using JavaFX and Scene Builder (the GUI editor for JavaFX) to start building some business applications at work.

    The demos provided by some of the community served as proof of concept to me that JavaFX is something special. E.g. Gerrit Grunwald’s (@hansolo_) set of gauges in the JFXtras project show what can be achieved with a little time and artistic flair.

    On the OS X front, it looks like we’re all set to go now with the Mac App store. The javafxpackager tool provides the ability to easily deploy applications as native bundles. This is a new direction for Java (up until now, they have been recommending Web Start distribution), and I think it is a good one.

    Another topic that I am keenly interested in is mobile development (iOS and Android). Last year’s java one included a demonstration of JavaFX running on an iPad, but then nothing more was heard. This year they announced that JavaFX will be available for Java7 SE Embedded, and they had a conference scheduler application running on an small, embedded device in a kiosk at various stations in the conference. But there were no announcements about JavaFX for iPad or Android. The announcement of its availability on embedded devices is a step in the right direction, though, as this is a prerequisite for running on the major embedded platforms.

    I did attend one talk (actually 2 talks on the same topic) on Java for iOS and Android. The CodenameOne project (that I’ve blogged about before) is a java library and framework for building cross-platform mobile apps (i.e. deployable on Android, iOS, Blackberry, and J2ME). This looks very promising.

    When I had reached my saturation point on JavaFX, I wandered across to the Parc55 building for a couple of Java Enterprise Edition talks. I attended a talk on the new Project Avatar, which provides a thin-server approach to web applications (i.e. most view logic and layout is handled on the client in javascript, and the server just sends over the data). This project looks quite interesting, both in concept and execution. The concept coincides with much of the more recent development I’ve been doing with Xataface.

    The last talk of the conference that I attended was on NoSQL and scaling strategies. There, Nike’s director of engineering discussed some of their architectures for handling heavy traffic with NoSQL databases and Data grids.

    My head is full. My notebook is full. Now to put all of this new knowledge into practice.

    “Engineers” in the US

    During the course of a dinner last night, a “canadianism” was brought to my attention that I was quite unaware of. A friend of a friend who is working at Google mentioned that the project he is working on is “quite small”. When I asked what “quite small” meant, he responded with “about 100 engineers”. Wow, I thought. “If this project has 100 engineers, how many software developers does it have?”, I asked naively. He responded that, in the US, software developers ARE engineers. It is just the language. If you develop software, you say you’re an engineer. Of course they mean SOFTWARE engineer, but I note that this first part is omitted by default.

    In Canada, the word “Engineer” is a professional term reserved for professional engineers. These are people who have a special P.Eng. designation, and who put their designation on the line whenever they sign off on a project. Engineering is a profession, like doctor or lawyer. Just as you cannot practice law without being a lawyer, you can’t be an engineer without your certification.

    Software Engineering, though it exists, is not a profession in the same sense, and it perhaps never will be. The absence of an official designation appears to have led to a dilution of the term to the point where it has no meaning. All these years, when people have asked me what I do, I have always responded with “Software Developer”. Apparently, when talking to Americans, I can now call myself an engineer.

    If I were a real engineer, I’d take offense. But I’m a software developer, so I’ll take engineer.

    Ingredients required to port HTML/Javascript App to JavaFX

    I have been taking in as many JavaFX talks during Java One as I can. I’m keen to move some of my development from LAMP/HTML5 to LAMP/JavaFX (Yes.. still not ready to move into the JavaEE space – though PLAY makes it compelling).

    The Scene Builder application, complete with its powerful CSS support, looks like it will make the UI portion of app development quite easy. In fact, I suspect it may even improve my productivity over my existing HTML development.

    The one piece that I’m concerned about is the HTTP client for consuming the LAMP web service. In Javascript you get quite a bit for free, but the two biggest are:

    1. Sessions/Auth are automatically retained.
    2. AJAX calls and conversion to/from JSON is automatic.

    To replicate the functionality in a JavaFX app, I suppose I need to embed an HTTP Client object of some kind to maintain all of the session information and allow me to load JSON data sets from the server in a simple manner. At the “JavaFX for Business App Developers” talk, the speaker used Jersey in is example application to consume an XML web service. The Jersey website makes it sound like it can also be used to consume JSON web services. Will have to give it a try.

    Another option, which I’ve yet to try, is to actually embed a Web Engine into the app for dealing with AJAX calls. This is either a very good idea, or a very bad one. I would be concerned about such things as performance, and security restrictions that may exist inside the web box.

    I’ll post again with my findings.