Thursday, 21 October 2010

Apple's Java runtime "deprecated": less news than we might think?

Web news outlets have picked up on a comment in the release notes for the latest Apple Java update saying that Apple's version of Java is now deprecated and will receive less frequent updates. The new Mac App Store doesn't permit Java applications, so some, including The Register, have concluded that Apple is trying to kill Java on the Mac.

This time, I think they are seeing conspiracy theories unnecessarily. (For all I know, Apple might well want to kill Java, but this change makes sense even if they don't.)

When The Register first published their story, the author conflated "Java" with "Swing". The original version of the story, when trying to describe the few desktop apps that require Java, linked to a list of apps that use the Swing toolkit. And so, for instance, didn't include significant applications like Adobe's Flash Builder 4, which uses SWT not Swing. (The Reg has edited the story since then.)

Why does that matter? Well, at JavaOne Oracle trumpeted JavaFX not Swing as the way of the future for Java user interfaces. Oracle's JavaFX roadmap promises a Java plug-in that runs JavaFX without even starting the old abstract windowing toolkit (or, consequently, Swing). But the most visible part of Apple's investment in their own Java runtime has been making Swing look nice and work well on Apple desktops. So it sounds like Oracle effectively deprecated a lot of Apple's work for them!

Just under where Apple's release notes say "Java Deprecation", it immediately headlines "Third Party JVM Support" (effectively, making it easier to put Oracle's Java runtime on the Mac instead of Apple's.)

Meanwhile, the SWT toolkit that Eclipse and Adobe Flash Builder 4 use already the Mac's "Cocoa" bindings even when not using Apple's Java runtime. So those guys, including a lot of Java developers who use Eclipse, probably won't even notice a bump -- their interfaces should look identical on Oracle's runtime or on Apple's.

All in all, it seems as though deprecating the Apple Java runtime is an attempt to move Mac users to the Oracle Java runtime, not actually a nefarious "kill Java" machination after all.

Edit: The thing I'm trying to speculate, without overstepping the mark (it is just speculation), is that I reckon Oracle might have wanted this change to happen. Oracle's recently announced JavaFX roadmap promises a new browser plug-in. The browser plug-in for Java is normally part of the JRE. That suggests to me that Oracle would already have been thinking about whether they needed to take over providing the Mac JRE in order to deliver on their roadmap fast enough.

That could still be very worrying news for Swing/AWT on Mac, though.

Tuesday, 19 October 2010

Another JavaFX mistake: LoggerFactory.getLogger(this.getClass())

Every now and then I come across a mistake in our code (either mine or someone else's on the team) that demonstrates something about the JavaFX compiler -- a behaviour that breaks a hidden assumption that programmers sometimes have. Here's another one:



That code's got a potential mistake in it -- if you instantiate a subclass of AlignedContainer, the logger's name won't be AlignedContainer, but the name of the subclass. In JavaFX, the compiler generates subclasses for object literals, and you'll find that many of your loggers are named after generated classes.

So, in this particular case the logger ended up being

au.com.nicta.cose.comlex.fx.TimelineGui$1AlignedContainer$ObjLit$17

Which is a more awkward to turn on or off individually using log4j.properties (notice that one of the generated parts of the name, "TimelineGui$1", comes before "AlignedContainer"). Why is this the case? Well, the AlignedContainer was instantiated using an object literal:



The JavaFX compiler neatly generates an inner class extending AlignedContainer to implement this object literal:



So then it makes sense that this.getClass() does not return the AlignedContainer class but this anonymous inner class.