O'Reilly Network    

 Published on The O'Reilly Network (http://www.oreillynet.com/)
 http://www.oreillynet.com/pub/wlg/2933

What's up with Mac OS X Java and QuickTime?

by Chris Adamson
Mar. 20, 2003

Some developers who installed Apple's new java 1.4.1 for Mac OS X (and didn't read the release notes or the mailing lists) got a nasty surprise when they tried to run apps they'd written for use with QuickTime for Java:

cadamson% java -classpath PlayMovie.zip PlayMovie
Exception in thread "main" java.lang.NoClassDefFoundError:
com/apple/mrj/macos/carbon/CarbonLock
  at quicktime.jdirect.QTNative._getLock(QTNative.java:111)
  at quicktime.jdirect.QTNative.(QTNative.java:105)
  at quicktime.QTSession.(QTSession.java:114)
  at PlayMovie.main(PlayMovie.java:24)

What's happening is that java 1.4.1, now the default when you type java on the command line, does not support certain Java-to-Carbon technologies that QuickTime for Java depends on. This problem was hinted at in a previous QTJ article, but I had to address the issue indirectly, since Apple's 1.4.1 was still under NDA.

So why so much breakage? The story, as well-covered by MacDevCenter's Daniel Steinberg in Apple Releases Java 1.4.1 for Mac OS X is that Apple has made a huge under-the-hood change, swapping out an AWT/Swing implementation based on the Carbon API for one built on Cocoa.

The change is quite significant, as the move to the object-oriented, multi-threaded Cocoa environment appears to have significantly simplified Apple's java codebase. However, it now makes calls from Java into Carbon code much more difficult. As explained in a java-dev message from Apple's Java Project Manager, balancing between the pre-emptive threading of Java with the co-operative threading model of Carbon is a tricky proposition.

As a result, in many cases, they've decided to replace or simply abandon the Carbon-bound java extras. The com.apple.mrj packages used to access Mac-specific features are now deprecated, replaced in part by com.apple.eawt and com.apple.eio. In fact, the term "MRJ", a holdover from the old Mac OS' "Macintosh Runtime for Java" era, seems to be going away. Also gone is the "JDirect" API for simplifying java-to-native calls.

Notice that both terms, "MRJ" and "JDirect" are implicated in the stack trace above. The QTJ code tries to get the carbon lock to avoid hosing the Human Interface Toolbox, but the com.apple.mrj code to do so isn't available in 1.4.1.

However, the situation is not as bad as it might sound. java 1.3.1 remains in place after a 1.4.1 upgrade, and will still run QTJ apps, and will reportedly be included in the next major release of Mac OS X. And in some cases, 1.3.1 will be the default JVM, for example, if your app is distributed as a .app bundle -- the schemes for every scenario are spelled out in the release notes. You could force use of 1.3.1 by using Java Web Start, or by using a shell script that explicitly calls /System/Library/Frameworks/JavaVM.framework /Versions/1.3.1/Commands/java, although the latter option is fraught with peril if a java 1.3.2 is ever released.

With java 1.3.1 sticking around on Mac OS X for the foreseeable future, and with ways to call it explicitly, there doesn't seem to be need for QTJ developers to panic just yet.

Still, the future of QuickTime for Java does seem to be up in the air. It has not been explicitly canceled or deprecated, as have other API's, but it clearly and unapologetically breaks in 1.4.1, which makes a lot of QTJ fans nervous.

It's strange because until now, QTJ had seemed like a first-class citizen in the QuickTime world, prominently featured in developer documentation (the main QuickTime API documentation even cross-references all Java equivalents to the native API's calls). Yet on the QuickTime for Java page, Apple says it is "interested in hearing from QuickTime developers and understanding what aspects of the technology they are using", as if it needs a business case to be made to commit to the technology (or some subset of it) going forward.

From what I've seen, QTJ interest is greater than it has ever been, a beneficiary to some degree of Sun's neglect of the Java Media Framework, which has not seen a major version since 1999, as Sun's media team has focused on a Mobile Media API instead. Developers who want to do media apps in Java are choosing between several imperfect options:

  1. Stick with JMF despite its limited collection of supported media formats and codecs. This is still the most practical all-java option.
  2. Use QuickTime for Java and get great support of real-world media types, and arguably the best API for editing and creating media, with the gotcha that it only works on Windows and Mac (and now only on 1.3.1 on Mac)
  3. Do everything yourself in Java like JavaZoom did with their all-Java MP3 decoder. Not for the faint of heart.
  4. Use JNI to tie into QuickTime, Windows Media, the Helix software open-sourced by RealNetworks, or other native media API's. Also difficult, and obviously limited to a handful of platforms.
  5. Dump Java and use the aforementioned media API's in their native format.

My fear is that if QTJ is not supported in the future, that option 5 will be the default, i.e., it will pretty much close the curtain on developing media applications in java, because the other options are too much work for too little benefit. And that will make developers like me wonder if we like QuickTime so much that we're ready to give in to the crazy square-braces and semi-automatic garbage collection of Objective-C. Time... or is that QuickTime... will tell.

Chris Adamson is an author, editor, and developer specializing in iPhone and Mac.

oreillynet.com Copyright © 2006 O'Reilly Media, Inc.