MacDevCenter    
 Published on MacDevCenter (http://www.macdevcenter.com/)
 See this if you're having trouble printing code examples


Java Programming on the Mac

Shell Scripts, Command Lines, and Classpaths

by Daniel H. Steinberg
10/02/2001

If you've come to Java programming on a Mac from a Windows environment, you've probably noticed that things are a bit different on the Mac.

A couple months ago, we looked at packaging Java applications using MRJAppBuilder. Last month, we ran through an introduction to GUI programming in Java on the Mac.

This month we look at issues involving classpaths and running applications from the command line and through shell scripts. This is not the way you'll usually distribute your applications to end users. You will, however, find that applications aimed at developers will require that you run them from the command line or through shell scripts. On a Windows box, you can double-click on a .bat file. With Mac OS X, you'll need to package them up using these basic techniques.

Java and XML on the Mac

At this year's JavaOne conference, Sun announced that it would provide a collection of its Java APIs for XML called the JAX Pack. Much of the technology would find its way into the releases of J2SE, but as J2SE is now released every year and a half, the JAX Pack is updated quarterly. If you've poked around the J2SE 1.4 beta, you know that it includes JAXP (the Java APIs for XML parsing). Mac OS X developers don't have a version of the 1.4 beta to play with on our boxes, but this shouldn't keep us from joining in the fun. Incidentally, a Java-friendly, open-source alternative to JAXP is JDOM. This article will also take a quick look at Xeena, the XML editor from alphaWorks.

Comment on this articleThose of you who have tried Java programming in the Mac environment, what do you have to say?
Post your comments

In this month's article, you'll download and install JAXP and take it for a test drive. This involves creating shell scripts or modifying your .tcshrc or .login files. You should be warned that I don't know anything about Unix that I haven't discovered through fooling around with Mac OS X. If there are nicer ways to accomplish these tasks you should post feedback to this article and email James Duncan Davidson demanding that someone take away my key to the O'Reilly writers' lounge (like there is one). This material is intended to help those of us that have been used to setting classpaths on a Windows box better understand the way Unix-heads think.

Next month, we'll return to the comfort of programming in Java and begin to develop an application that works with XML and shows off some of the Mac's special features.

Getting JAXP

Head to Sun's XML site. Follow the JAXP link and choose to download the JAXP reference implementation from the list at the right of the page. You will have to log in as a JDC member (if you're not a member, you can join for free). You can follow way more steps than you need to, or just navigate to http://java.sun.com/xml/download.html and download the final version of JAXP 1.1. Unzip the file into the Applications directory of your home directory. In my case, that's in /Users/dhs/Applications. You should replace dhs with your user name. Finally, change the name of the directory from jaxp1-1 to jaxp so that these instructions will remain relevant for future releases.

Related Reading

Java and XML, 2nd Ed.Java and XML, 2nd Ed.
By Brett McLaughlin
Table of Contents
Index
Sample Chapter
Full Description
Read Online -- Safari

Really the only thing left to do is to make sure your classpath is set correctly to find three .jar files: jaxp.jar, crimson.jar, and xalan.jar. The easiest way to do this on a Windows platform is to copy the three files into the /lib/ext directory (or as they put it, your \lib\ext directory) where your Java distribution is. You'll find this on your Mac in /System/Library/Frameworks/JavaVM.framework/Home. Go ahead and try to drag your .jar files from the jaxp folder into the ext directory. You'll be warned that this can't be done because "ext can't be modified." Sigh.

After your initial frustration, you may realize that this is probably a good thing for now. You don't have to worry about automatic system updates hosing your customizations. Just keep your jar files where they are for now and add that location to the classpath. You have three basic choices: (1) type in all of the commands on the command line, (2) create a .tcshrc or .login file that is read when you open up the terminal window, or (3) create a shell script that includes this information when you run a particular application.

I'll treat the third option in getting the Xeena application to run. I'll have a couple of quick comments on the second option and a pointer to another Mac DevCenter article at the end of the next section. Let's start with a look at setting up your classpath from the command line. If you've used ProjectBuilder, these are the red commands that stream by when you choose to build and run your project.

From the command line

Open up a terminal window and navigate to the jaxp directory. This is where the three .jar files are located, so create an environment variable called "JAXP" that points to this directory as follows.

setenv JAXP /Users/dhs/Applications/jaxp

Again, you will use your own user login in place of "dhs". Next, you will set an environment variable to hold the additional classpath information using the following command:

setenv CP $JAXP/jaxp.jar:$JAXP/crimson.jar:$JAXP/xalan.jar:.

The $JAXP is replaced by the value of the JAXP variable that you previously set. If you come from a Windows background, note that you need to use colons -- and not semicolons -- to separate the entries. Finally, you include "." so the current directory will be in the classpath. Now navigate to the jaxp/examples/SAXTagCount directory and compile the example SAXTagCount.java like this.

javac -classpath $CP SAXTagCount.java

The compiler will quietly churn and return a prompt. Now you are ready to run the example program. You need to pass it an XML DTD for which it will count the various tags. In the directory jaxp/examples/samples is an XML version of Shakespeare's Richard III called rich_iii.xml and the accompanying Document Type Definition, play.dtd. You can have SAXTagCount count the tags in Richard III with the following command.

java -cp $CP SAXTagCount "../samples/rich_iii.xml"

Your terminal window should look something like this.

Screenshot.

You can use option (2) for storing the values of the environment variables in a .tcshrc or .login file. See James' article on finding his $JAVA_HOME for perspective.

One note for newbies -- you won't see the .login file if you are using your Finder. If you open up a terminal and type ls you still won't see these hidden files. You need to type ls -a to see them. There are a couple of strategies for creating and maintaining them. You can create them with TextEdit and then use the command cp login.txt .login to copy the file login.txt to one named .login.

The advantage here is that login.txt is not hidden and you can open it up again with TextEdit, change it, and then do the same trick to save it as .login. Of course, you can also use emacs and vi to edit these hidden files. My favorite solution, however, is to use BBEdit. BBEdit has an option in the File menu to "Open Hidden". When you select it, you can see the hidden files, open any one of them, edit it, and save it.

XML editors

You can edit an XML document with a simple text editor. In a way, that's the point of XML. On the other hand, XML files are hierarchical and it is nice to be able to see this structure when creating a file. For example, if you look at the play.dtd file it specifies the various components of a <PLAY>. You can see what a <PLAY> contains and in what order. A <SPEECH> can be contained in a <SCENE> that is in turn contained in an <ACT>. A <SPEECH> consists of a <SPEAKER> followed by one or more elements chosen from <LINE>, <STAGEDIR>, and <SUBHEAD>.

The idea for this article actually came when I started to play with the ElfData XML Editor available for download on the Apple web site. Here's a look at Richard III using this application.

Screenshot.

On the one hand, this is a nice hierarchical view of the play. But if I alter Shakespeare by adding a <SPEECH> after this one, then right after I add the new <SPEECH> I should somehow be prompted to add the <SPEAKER> element as every <SPEECH> must begin with a <SPEAKER>.

As I looked around at other XML editors, I saw a familiar story. For the most part, the applications were Windows-only and none of them listed Mac OS X as a platform. And then I remembered Xeena. It is available for free and is a Java application. It has to work on Mac OS X -- right? Download the distribution and expand it and save it in the /Users/dhs/Applications directory (where again you replace "dhs" with your user name).

Shell scripts and running Xeena

Now that you've got Xeena downloaded, rename the directory xeena. Inside you'll find a lib directory that contains all the .jar files needed by this application. You'll also see .bat and .sh files used to run Xeena and various examples on Windows and Unix platforms. Take a look at the xeena.sh file. It is way too complicated. One of the advantages of running a Java application on Mac OS X is that you don't have to wonder about which virtual machine is being used and where it is. You can dramatically simplify the shell script so that xeena.sh consists of the following:

XEENA_HOME=/Users/dhs/Applications/xeena

JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home

CP=$XEENA_HOME/lib/xmleditor.jar:$XEENA_HOME/lib/xerces.jar:
  $XEENA_HOME/lib/jgl3.1.0.jar:$XEENA_HOME/lib/xalan.jar:
  $JAVA_HOME/classes.zip

java -cp $CP  com.ibm.hrl.xmleditor.Xeena $*

Note: The third item in the listing above should be all on one line, with no spaces between the ":" and the following "$" -- the line has been broken here for the sake of the display.

This should look familiar from your earlier experience. You are setting the location of the Xeena directory (yes, you should replace "dhs" from /Users/dhs/Applications/xeena with your own name). JAVA_HOME points to the home directory for the Java installation. You are then using these variables to set the classpath to point to the four jar files required by the application as well as the Java classes. The final step is to run the application from the jar file xmleditor.jar. You can now run Xeena by running the shell script. You could type this.

sh xeena.sh

You don't get much for your money. You need to pass in information such as the name of the DTD, the root element, and the XML file that you're editing. To see an example, run one of the examples. For instance, type the following:

sh sample_dtd.sh

This brings up the following address book example.

Screen shot.

The application helps you insert the correct elements according to the specified DTD. More importantly, you now can create, edit, and run shell scripts.

Daniel H. Steinberg is the editor for the new series of Mac Developer titles for the Pragmatic Programmers. He writes feature articles for Apple's ADC web site and is a regular contributor to Mac Devcenter. He has presented at Apple's Worldwide Developer Conference, MacWorld, MacHack and other Mac developer conferences.


Read more Java Programming on the Mac columns.

Return to the Mac DevCenter.

Copyright © 2009 O'Reilly Media, Inc.