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$1AlignedContainer$ObjLit$17

Which is a more awkward to turn on or off individually using (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.

Wednesday, 29 September 2010

JavaFX Script isn't in JavaFX 2.0 - what's the practical impact for working with JavaFX now?

from my JavaOne talk.

At JavaOne, it was announced that JavaFX 2.0 won't support JavaFX Script. (Or at least, Oracle won't be updating the JavaFX Script compiler for JavaFX 2.0.) Although Oracle had kindly given partners and speakers a little advanced warning of this, I met quite a few people at JavaOne who were taken by surprise. And at face value, the situation today is a little odd:
  • JavaFX 1.3.1 requires you to write in JavaFX Script
  • JavaFX 2.0 won't let you write in JavaFX Script
  • (and 2.0 isn't out until next year)
And many people find themselves in a dilemma: Does that mean all code for 1.3.1 has to be thrown away? What do you do until 2.0 is available if you can't just "wait a year" -- 2.0 code can't be written yet but 1.3.1 code would be wasted?

After rejigging my talk a little, I inserted a few slides on what I think the practical impact on our project is in the short term. After all, my team has a JavaFX 1.3.1 client. How has this announcement affected us?

Well, the first thing to say is that even today a lot of a JavaFX client can be written in Java. I ran some rough line counts on our JavaFX client -- the client I demo'ed at JavaOne -- and it came up as:
  • 27% JavaFX Script
  • 73% plain ol' Java
So the impact for us is a bit smaller than it appears. Part of that is because I was very cautious about committing the client to JavaFX. JavaFX 1.2, which we had to cope with until April 2010, had some very awkward bugs in it -- and there seemed to be a lot of risk with the Oracle buy-out and JavaFX gaining little market-share. So I kept as much of our code as possible in Java, ready to jump ship from JavaFX if we needed to. The libraries, model, data handling, and most of the guts of our code aren't written in JavaFX Script but just in Java. And it seems that's just as well. I realise other projects might not be in that situation though.

So this seems to be rule 1 for working with JavaFX at the moment:

If a class doesn't have to be written in JavaFX Script, write it in Java, Scala, Groovy or some other JVM language. Save yourself the effort of converting it later.

Various talks at JavaOne described possibilites for working in a JavaFX-Script-like way in JavaFX 2.0:
  • Stephen Chin is keen to get an open source project going to update the JavaFX Script compiler so it can target 2.0
  • Jonathan Giles and Stephen Chin showed how code in Scala, Groovy, or Clojure can look very similar indeed to JavaFX Script
In my view, it's too early to assess whether it will be easy to convert non-trivial JavaFX Script code to Scala or another JVM language. The 2.0 libraries are still being written, and nobody has much experience converting non-trivial apps yet -- even some of Oracle's demos in Richard Bair's JavaFX 2.0 talk were still written in JavaFX Script code; they hadn't been converted yet. It should be straightforward -- the 2.0 libraries are supposed to contain all the functionality of the existing JavaFX, so it should just be a matter of converting syntax, not redesigning your client. But let's wait and see on that.

It's also to early to assess whether the open source project to update the JavaFX Script compiler will be successful or not. Again, it should be. The JavaFX Script compiler always compiled to Java, and under 2.0 it'll have some libraries to target that will be a very close mapping to its language features.

So what can you do now?
  • JavaFX 1.3.1 is a production release. And it works pretty well. (Unlike, say, 1.2!) So in the short term, targeting an app at 1.3.1 isn't so bad.
  • JavaFX Script is still very fast for prototyping. Many of our visualisations were written in hours, not days. If you are doing prototyping or scientific experimentation where the results and the design decisions are more valuable than the code, JavaFX Script is still a pretty good choice.
  • If you do keep most of your model code in Java, then the JavaFX Script code you write will usually be fairly simple. That means it's going to be less complicated to convert to another language if you decide to.
For my project, in fact, JavaFX Script not being supported in 2.0 makes very little difference. Government-funded research projects get fixed funding periods, and our current funding round finishes before 2.0 will be released. So we couldn't target 2.0 anyway. (If our hospital partners' experiments are successful, and more funding is won to take it further, that'd come with more development funding to deal with productisation issues -- including upgrading from 1.3.1 to 2.0. We'll make that as easy as possible to do, but we don't have to pencil it into the calendar yet.)

Tuesday, 28 September 2010

Checked and unchecked exceptions in Java

Over on Stephen Colebourne's blog, there's a discussion on whether checked exceptions in Java were a bad idea.

It seems to me that if you declare an exception as being a checked exception, you're effectively making three claims:

  1. You can't programmatically prevent this exception from occurring.
    Declaring checked exceptions requires you to put in code to recover from the exception.  It makes no allowance for code that actually won't ever cause the exception in the first place.  You can swear blind "No that can't throw a MalformedUrlException because I already know is well formed", but the compiler will require you to catch a MalformedUrlException nonetheless.  (That trivial example could, for instance, be irritating if you've got a little throwaway app where you want to declare a URL as a static final constant.  The checked exception gets in the way even though it will never be thrown.)
  2. You're so likely to forget to handle this case, and it is likely enough and serious enough to occur, that I'm going to force you to decide how you're going to deal with it right now ...
  3. ... but it's not so terminal or abnormal that most applications shouldn't try to catch it
    (That's Error.)

Item 1 in that list makes me think checked exceptions should be rare.  Prevention is sometimes better than cure, but checked exceptions force you always to write a cure -- even if you've already prevented it.

But rare is not the same thing as non-existant.  Personally, I think File IO exceptions being checked is reasonable, for example.

Wednesday, 22 September 2010

JavaOne slides & Thanks for listening

I just wanted to say thank you to all who came to my talk today. Especially as I know there was a much higher profile JavaFX Graphics talk going on in another room at the same time. (Yes, that was a bit demoralising!)

I deliberately skipped some of the technical slides in the presentation -- this is because they are particular to JavaFX Script (deprecated in 2.0). The slides were the top few most hair-pulling bugs we came across in our JavaFX Script code. Things my team wished someone had told us before we started.

But to make sure you don't hit the same issues if you do any JavaFX Script, I have uploaded all the slides (including those) to Slideshare. The code examples should explain the problems reasonably well, and if not then please do ask.

Those slides are tucked in at the end of the presentation (91-106!). No, I didn't really expect to have time to show them -- when the 2.0 changes were announced, I thought it would be more useful to talk about the practical impact of the "death of Script", rather than talk about some technical traps in a language that's been discontinued.

Tuesday, 21 September 2010

Things to expect in my JavaOne talk on JavaFX, OSGi, and the science of good (medical) conversation

Things to expect in my talk on Wednesday at JavaOne:

Wed 22nd Sept, 16:45 Hilton San Francisco, Golden Gate 3:
Visualizing the Science of Conversation with JavaFX and OSGi to Save Lives. William Billingsley, senior research engineer, NICTA
Session S313951
  1. A JavaFX demo that isn't yet another video wall.  Not even wrapped around a big ball and rolling down a slide into yet another video wall.
  2. The fastest, and hopefully clearest, introduction to OSGi.  We use OSGi on the client
  3. A little commentary on the JavaFX 2.0 changes.  How to sensibly use JavaFX 1.3 given it requires you to use JavaFX Script and that's going away next version.
  4. Programming as experimentation.  What do you do when it's actually a requirement that your requirements are unknown, and the goal of your software is to mine how your non-yet-users think.
  5. What the picture below means, and why JavaFX on Mac finds it harder than a video wall.

  6. How OSGi lets us build the great wall of science... this picture knows what you're talking about...

    ...and how this one knows how hard you were thinking when you said it.

Saturday, 18 September 2010

Science, JavaFX, and OSGi: appearing this week at JavaOne

On Wednesday, I'm giving a talk at JavaOne on how my team is using JavaFX to analyse and visualise medical conversations -- JavaFX in a scientific app, all pluggable and extensible via OSGi.
Wed 22nd Sept, 16:45 Hilton San Francisco, Golden Gate 3:
Visualizing the Science of Conversation with JavaFX and OSGi to Save Lives. William Billingsley, senior research engineer, NICTA
Session S313951
There have been a few lists of interesting JavaFX talks at JavaOne posted to Twitter and on the Web, and a few of those lists haven't included my talk. How to scare a speaker in one easy step: post a list of interesting talks on his topic and don't include his!

So, I just wanted to reassure anyone who's thinking of coming to my talk that yes it is on, and it should be relevant and interesting. (Or if it's not interesting, tell me off!)

A little later, I'll post more on what you can expect to hear at my talk.

Wednesday, 31 March 2010

Scientific rumours from CERN

As you may be aware, the CERN large hadron collider performed it's first high energy collisions just the other day. The official statements are that it will take many months or even years to collect and analyse the data. However, early data already suggests some interesting findings.

Not one not one but two kinds of strangelet appear to have been created. The first turns other particles into strangelets as it contacts them. This might have caused a world-ending reaction had it not been for the second kind. Once a sufficient density of the first strangelets exists in an area, a kind of anti-strangelet appears. This exerts a strong attraction force on other particles, and causes the first strangelets to revert back to normal matter. The strong attraction force suggests this might be an unexpectedly different form of the long sought-after Higgs particle, though this is yet to be confirmed.

The scientists have informally dubbed the first strangelets as "wise particles" or "cluons" as they mimic the way knowledge is passed from person to person. The opposite strangelets' flocking behaviour and cancellation effect on wise particles has led to them being dubbed "fools".

So, today April 1st, scientists can claim to have identified Higg's Bozo.

Monday, 29 March 2010

Programmer interviews and coding tests

Jeff Atwood has another blog post up about how "the vast majority of programmers can't program at interview".

Having interviewed programmers, and having thought about this problem from a human factors perspective, I've usually come to the conclusion that coding tests at interview are, in the end, almost useless.

Let's describe this using a slightly different story...

Suppose I was interviewing someone -- let's call him Bert -- for a human factors job. I ask him:
"Bert, why do you think programming interview candidates usually fail simple coding tests, even when all the other empirical evidence (their career thus far, references, and degree from a top rated university) suggests they should be competent?"

And Bert responds:
"Because they're just all that dumb; top tier university professors are fools who can't assess students; the exam results are all fake; and programmers' bosses are all just bozos that can't see whether any code is being produced even if they are programmers themselves. The empirical evidence from the rest of their careers is wrong and my toy interview question asked by an untrained interviewer over the telephone is right!"

Bert would not be getting the job. (However much the grumpy misanthrope in me might want to cheer him on in railing against the world!)

Like it or not, coding at interview is very different from coding on a job. To use a loose analogy: a great many people struggle at public speaking -- shove a microphone in front of them and ask them to talk for a minute about rain, and they say "Um, er, um... Mummy can I go home now?". That does not mean they don't know English or what rain is. Dumbing the question down to "Ok, just talk about water then" doesn't solve the problem - because it wasn't the topic that was the problem in the first place.

In an interview, we have a fake task (nobody wants to use the code), in a fake setting (an interview), via a false interaction (over the telephone!), with a false assessment (one interviewer whose word is final, no compiler, no user, no sales, no code metrics or unit tests), a fake timeframe (a few minutes on each 'project'), false pressures (your job depends on the next ten lines of code), and somehow we expect to have valid results. Speaking as a scientist, that's just nuts.

At this point, most people reply "Sure, but we don't care about missing out on good candidates, only not hiring bad ones." I have worse news for you. You are probably still hiring as many bad candidates as if you selected your candidates by rolling dice. Most interview coding tasks are so over-simplified that they no longer select for programming or thinking skills at all -- the "programming on stage" skill dominates completely. The irony is that by selecting for "skill at interview coding tasks" you might find yourself effectively selecting for people who have done a lot of interviews and honed that skill -- but you actually want to hire the person who has hardly done any interviews because no company ever wants to let him leave.

Tuesday, 9 March 2010

JavaFX initialisation order (solved?)

The semantics of JavaFX's initialisation order can be hard to find, and in a previous post, I was finding it gave some odd effects. Having looked on the JavaFX bug tracker, it turns out it the issue is fairly simple, but needs trumpeting from the hills because it is still unexpected. will be null. How is that possible? Because of what override means -- it changes the definition but not the "order of declaration".

A naive person might think that would first be set to 1 (in the initialisation of A) and then to 2 (in the initialisation of B). Or they might think that B.two will be set before because it comes first in B's script. But that's not how JavaFX does it. The variable one is initialised first because it is declared first (in A's class declaration, which comes before B's.) But it is set to B.two because only the override initialiser takes place. Unfortunately, this means it is set to B.two before B.two has actually been defined -- so it gets set to null.

The moral of the story: Don't use override var if you want to set the variable to refer to another member variable. It's a forward reference. Even if the member variable you want to refernce also comes from a superclass, it could still be a forward reference (because you don't know what the order of declaration was in the superclass).

If in doubt, set it in the init block. That always happens in the order that you specify in the block, after everything else has happened. It's boring and more Java-like, but at least you can even step through it with a debugger and put log messages in if you need to!

Tuesday, 2 March 2010

JavaFX initialisation craziness

UPDATE: Another post describes the solution.

JavaFX is Sun/Oracle's new user interface platform for Java. It has many features that are quite nice. But it has a few oddments that are hair-pullingly irritating.

The naïve among us might think that pushing the mouse button would indeed be wired through to MyBehaviour.onMousePressed, and "MOUSE PRESSED" would be printed. Apparently not.

In the language reference, there is this irritating line when it describes the initialisation order:
The values of the object literal's instance variable initializers are computed (but not set).

"but not set". Of all the evil villainous schemes... The MySkin and MyBehaviour objects are created, but isn't actually assigned until later, so the following line wiring the mouse events to it breaks.

I keep finding that JavaFX is wonderfully concise, but really tricky to debug, and irritatingly fragile as many of its conventions don't do what you'd expect (like let you refer to an assignment you made in the previous line during initialisation, as in this example).

Thursday, 25 February 2010

Australian Internet Filter

Senator Kate Lundy has made an alternative proposal for an Australian internet filter, bringing it back into the news again. However, her suggested opt-outs have not appeased everyone who is opposed to there being a government filter at all.
However, another kind of internet filter -- one that already exists and seeks to restrict access to sites -- has been remarkably successful and has not had the same kind of fuss made about it. That is the filter that modern browsers have built into them to block phishing and other fraudulent sites. Many browsers check a blacklist of URLs and if you try to visit a page on the blacklist, you'll have to click through a very serious warning first.
However, surely this also makes the gradual introduction of an optional government filter rather easy. If the government simply maintains a database of sites and the social or legal reasons why they might be inadvisable, the browser manufacturers could be nudged into showing appropriate warning boxes for them too. The rationale would be that if a person visited a site that had been officially declared a source of illegal material they'd find it hard to argue that they didn't know it was a bad site. So the browser publishers might start to feel they should protect their users from legal trouble just as they currently protect them from fraud.
I suspect a warning along the lines of "keep visiting this site and the police will be after you" is one that few people would ignore.