Category Image In defence of Cocoa-Java. 


The Cocoa-Java bindings get a rough ride in some circles, and for good reason. Still, there are times when it makes sense to take advantage of this technology. 

Who am I to argue with a Cocoa expert like Aaron Hillegass? In Don't Write Cocoa Applications with Java, Mr. Hillegass warns developers away from developing using Apple's Cocoa-Java Bindings. Mr. Hillegass is a well-known expert in Cocoa and Objective-C, and offers an excellent argument for developing Cocoa applications in Objective-C. Objective-C is, after all, the language Cocoa is developed in.

I have to agree on one point -- if you're starting a new Cocoa project, why would you want to use Java, when Objective-C is the language the majority of Cocoa developers, Apple included, work in? There probably aren't too many good reasons to do so, nor would I argue that you should.

However, what if you have a large, complex, and mature library written in Java that you'd like to access from within a Cocoa application?

This is the situation I found myself in with the Cocoa jSyncManager (which is currently not publicly available due to a lack of a usable Java USB API on Mac OS X). On one hand, I wanted to write a Mac OS X specific version of the jSyncManager, which took advantage of some of the more advanced (and platform specific) GUI design one can do in Cocoa that is difficult (or impossible) to do in Java. On the other hand, I have over 20 000 lines of object-oriented, multithreaded code in the jSyncManager API which has been under development for more than six years, and which encompasses 5 different protocols, usable over serial ports, modems, USB ports, TCP/IP, and Bluetooth.

GUI development is (or at least should be) easy stuff, but the kinds of things the jSyncManager API is doing is "hard stuff". Rewriting it in Objective-C would be extremely time consuming -- it would not only need to be completely rewritten from the ground up, it would also need to be extensively tested and debugged to get anywhere near the level of speed and stability (never mind the feature set) that the jSyncManager API already has.

GUI development is one of the things that Cocoa does correctly. Interface Builder is every GUI developers dream tool. Indeed, I've quickly become of the opinion that now that Sun has standardized on a serialization mechanism for Swing components that they should explore creating a Java version of an Interface Builder-like tool, which instead of trying to create source code to build the GUI elements at runtime, should instead work with live objects at design time which are serialized out to disk as a resource (more on this in a future blog entry).

So I want to write my own PalmOS synchronization application for Mac OS X. I have the jSyncManager API already written. I want a Cocoa UI atop it. Why not use Cocoa-Java?

Thus, going against the advice of the experts, I started working in Cocoa Java. The result? In less than four hours I had a working synchronization application with a native Mac OS X Cocoa user interface, and a pure Java back-end using an unmodified copy of jSyncManager API. And at least three quarters of that time was spent browsing Apple's Cocoa Java documentation to learn the framework better.

Now admittedly, the jSyncManager's GUI requirements are fairly simple. The jSyncManager is not a document-based application. It only has one main window, which is more of a status dialog:



And I do have to admit to using a tiny bit of Objective-C, although this may have to do more with my relative inexperience with Cocoa. As part of the development effort, I decided that I'd try to work as much in the Cocoa way of development as possible, and decided to allow Cocoa/Mac OS X to handle my applications preferences, in order to make it work the same as every other Mac OS X application out there. This meant using the NSUserDefaultsController class.

Now part of developing with NSUserDefaultsController is telling an instance of this class what the default values are. This is important, as an application like the jSyncManager needs some default settings to get started. Unfortunately, the defaults need to be initialized prior to loading the NIB file where my instance of NSUserDefaults lives, and as my primary class of my application is instantiated by the NIB, I couldn't figure out a way to set these defaults in Java. As Cocoa-Java applications do have a small Objective-C stub created by Xcode in order to start the application, I would up adding a few lines of code to my main.m to set the default settings. The only other obvious option was to create a launcher class in Java which would load the NIB file, and set the defaults there. In the end, doing this in Objective-C inside the existing source file was easier, and achieves the same result.

The result has been very successful. The handful of testers who have seen and used the Cocoa jSyncManager have been unable to tell the difference between it and a native Cocoa application, even in its early state of development. It launches quickly (or at least appears to launch quickly, as the NIB file is initialized and the GUI comes up promptly while the system continues to load the Java Virtual Machine in the background, and initialize the jSyncManager Synchronization Engine). It runs quickly. And it looks like a native application, because at least so far as the GUI is concerned, it is a native application.

I think Mr. Hillegass has very good reasons to steer people away from Cocoa Java development for new applications. But if you have existing Java libraries which you'd like to put a native Mac OS X GUI atop, Cocoa Java is an excellent solution to help rapidly bring your Mac OS X using customers an apparently native solution, without having to redo all of your existing work.

The Cocoa jSyncManager will be available in wider availability soon. Look for it wherever fine Mac OS X software is found. 

Posted: Sunday - May 29, 2005 at 03:47 PM          


©