Building Cocoa-Java Apps with Eclipse

Eclipse is a gloriously powerful, open source IDE*1, which is a joy to use when working with Java. Xcode, on the other hand, comes free from Apple, but doesn't quite like having to deal with Java--they get on fine together, but Xcode just doesn't go out of its way to make it fun.

Xcode's first love is Objective-C, and it shows.

It makes sense, then, when writing Java based Cocoa Applications, to use Eclipse. But how? What does Eclipse know about the esoteric world of Cocoa-Java? Well, with a little help from Ant, the flexible build system, you can tell it everything it needs to know.

This article will detail a simple method of building, and debugging, bundled Cocoa-Java applications that doesn't rely on keeping synchronized Xcode and Eclipse projects. Due to limitations on space, I'm assuming that you are comfortable with all of the referenced technologies--Eclipse, Ant, Cocoa-Java, etc. Having said that, it's straightforward enough.

Starting Off

To keep things simple, we'll be working with the sample project, TextEdit, in the Java AppKit examples folder, as installed with the developer tools.

As mentioned before, Eclipse knows nothing about Cocoa-Java and Objective-C. One easy way to get around this is to use the command-line tool xcodebuild to generate the application bundle and compile the Objective-C main stub. Everything else can be done as normal by Ant and Eclipse--Java files processed and .jar'ed, and the application bundle populated with all of the necessary resource files. Using this method means that we don't have to keep an Xcode project in sync with the Eclipse project. Xcode will not be dealing with anything other than the Objective-C files.

Get the Xcode Side of Things Ready

Make a copy of the Java TextEdit project and open it in Xcode.

Instead of writing an Info.plist by hand, simply build the
project and take Info.plist from the newly produced app in the
build folder (build/TextEdit.app/Contents/Info.plist). Copy the
info.plist to the main project directory where all of the
source code is stored.

Before closing Xcode, remove all of the non-Objective-C files
*2--remember that Eclipse and Ant are going to
look after everything else.

Getting Started with Eclipse

Create a new project in Eclipse and have it use the existing TextEdit files:

From the menu bar, choose File -> New -> Project and select
Java Project from the list of options. This will bring up the
New Java Project Wizard.

Enter the project name as "TextEdit."

Choose "Create project at external location" and browse to the
TextEdit folder. At this stage, Eclipse will indicate that it
knows that there are files already available in this folder and
that it will set itself up accordingly.

Click Finish to create the project.

Screenshot of the New Java Project Dialog

This will produce a project containing all of the files in the TextEdit folder. As only the Java files (and a few others, such as the Info.plist) are of interest inside of Eclipse, it may be useful to just turn on filtering in the Package Explorer to clean up the display a bit.

Open Controller.java and you will instantly notice that hundreds of errors are highlighted. At this point, Eclipse knows nothing about Cocoa, and therefore cannot find any of the Cocoa types referenced in Controller.java.

Tell Eclipse where to find the Cocoa classes:

Select the TextEdit project in the Package Explorer.

Choose Properties from the Project menu in the
main menu bar.

Choose Java Build Path from the list of options and switch to
the Libraries tab.

Click on the Add Class Folder button, and in the Edit Class
Folder dialog choose Create New Folder.

Enter "Cocoa" as the folder name and click the "< <
Advanced" button.

The advanced options allow you to link the new folder to an
existing folder. Click on the "Link to folder in the file
system" option and enter /System/Library/Java as the
path.

Hit OK to finish each of the nested dialogs that we've
brought up. After a second or two, all of the errors should
disappear, as Eclipse locates all of the Cocoa
references.

Eclipse comes bundled with Ant--a build system written in Java that is controlled via XML-based files. A dedicated editor is provided to help generate and edit the build files. You may find it useful to have the reference section of the Ant manual, which is part of the developer tools, open in your browser.

Getting Started with Ant

Create a new file in the TextEdit project and call it
build.xml, which is the default name for an Ant build file. The
newly created file will display an Ant as part of its icon
, and when you
open the file, the Ant Editor will be automatically invoked.

Open the build.xml file and choose Content Assist from the
Edit menu (normally mapped to the key combination Command-Space). Content Assist will display the available editing options
for any given situation. Choose the Buildfile Template to
create the stub of a new build file.

Set the project name to "TextEdit" and the Description to
anything you'd like.

Set the name of the first target to "build" and the depends
value to "jar".

Save the changes.

If it's not already visible, show the Ant View by choosing
Window -> Show View -> Ant.

Choose "Add Buildfiles..." in the Ant View and
select the newly created build.xml file in the TextEdit
project. Double-click any of the targets to run them.

Click on the Hide Internal Targets button to view only the more
interesting public targets.

You now have the skeleton of an Ant build file with a couple of targets defined and executable from the Ant View. Unfortunately, we don't have enough space to go through the build file line by line, so in the popular tradition, here's one we made earlier, along with its property file*3.

All of the targets in the build file are the normal targets that you'd find in any Ant build file; they clean, compile and .jar as you'd expect. The more interesting targets are described below.

The createAppPackage target is only executed if TextEdit.app doesn't
already exist in the build folder. If it's not there, the command-line
tool xcodebuild is called to create the application bundle, compile the
Objective-C main, and produce the executable stub in TextEdit.app/Contents/MacOS.
In other words, it automatically does the hard part for us. The last operation
of this target is to remove the automatically generated Info.plist.
Later on in the build, a new Info.plist file will be copied into
the correct location.

Sometime after the application bundle has been constructed, the populateBundle target is called. This target has only two simple jobs--copy in the new Info.plist and copy in the contents of the Resource folder.

The .jar target is the final target that we'll take a look at. The only difference between this and the standard .jar target is that the resulting .jar file, TextEdit.jar, is stored in the Contents/Resource/Java folder of the application bundle.

That's it--we have a completed build system that allows us to build a Cocoa-Java app from within Eclipse. Double-click the build file in the Ant View to produce an executable version of TextEdit. Run the build file a number of times after editing some of the Java files and notice that none of the steps are repeated unnecessarily. And finally, add a few new Java files to the Eclipse project and have them automatically included in the build without having to touch the Xcode project.