Netbeans day: arvo

The “JRuby: understanding the fuss” talk was very interesting. I was surprised to see how rich and “deep” the Ruby mode in Netbeans was. And step-debugging through lines in .rhtml files was a very neat trick. They asked how many people in the audience liked doing webapp development using their framework of choice. The response should neither shock nor surprise: very close to zero.

Tor found a few bugs in Netbean’s doco-popup support, which was funny for us and no doubt useful for him.

The JRuby presentation was structured very well, which couldn’t really be said for Gosling’s “Netbeans Toys” segment that came next.

Gosling was his usual self: excited yet monotone, and not giving anyone an inch. I suppose it is a hard task to come up with an interesting “toy” story involving Netbeans, and none of the presenters were up to the challenge. There were about 8 too many class diagrams in the RDF presentation (and, wtf, between alt-tabbing windows I could see his Inbox unread count; it went from 2800 one minute to 2934 the next). The JMF guy was dropping frames like there was no tomorrow. The best effort was put in by Bob Beasley and his D.O.R.K. device. I give the man full credits for showmanship, and those SunSpot jobbies look pretty cool.

Tomorrow: JavaOne day one. 9 hours on my feet, hopefully I’ll get to the Closure Technical session during the day, and the Closure and Java Posse BOFs in the evening. The Java Puzzlers TS will be a stretch-goal.

Netbeans day: morning

After a quick visit to the Apple store, I spent the morning at the CommunityOne event (ala Netbeans day).

The first general session included a chat by Jonathan Schwartz and Rich Green. Although they jumped around a little, they kept coming back to “Java is too hard” (Jonathan’s words). I suppose that it is a reasonable (or at least expected) schpeel if you are pushing a tools platform like Netbeans. That didn’t stop me from rolling my eyes when they said that; but at the same time there is a small part of me that said “damn straight”. That part of me is a little bugger to try and pin down and interrogate, so I don’t have much more to say on the topic yet; but I hear that voice all the time when considering new potential features like closures in Java.

After the general session, the Java Posse recorded a podcast. Definitely a funny bunch, and particularly gratifying that both FishEye and Crucible were in their “top 10 tools we use” list.

Laughing out loud

I work 99.9% of the time from home. But I keep in mostly constant contact with the gang through IRC and IM. This of course brings with it the usual accompaniment of standard (lol, rofl, bbiab, ack, nak) and non-standard (co=cool, swee=sweet, mo=mos=’o=morning) shorthand phrases.

Inevitably, at least for me, this physical-isolation but virtual-colocation has lead to me tuning down the physical component of communication. For example, I may not be actually laughing out loud even when I’m lol-ing on the inside.

So I always enjoy the time I get to spend with the boys at JavaOne, and as Conor’s weird look to me this morning can attest to, I still do laugh out loud (as seen on IRC and heard in the hotel room):

spud: as conor can confirm: laughing-out-loud http://xkcd.com/c258.html

JavaOne once again

Just arrived at San Francisco again, for this years JavaOne. Bee-autiful day here, just enough time for a quick blog from the hotel room before heading out for drinks.

Under reasonable experimental conditions

Some of they guys at work went to see Tim Minchin this week. Wish I could have gone, check out this great short song: “If You Open Your Mind Too Much Your Brain Will Fall Out (Take My Wife)” mp3 link.

Best cheesey-cheese

Like PragDave, I love a good cheese. Time for everybody’s favorite segment: my cheese story of the week.

For our recent anniversary Bron and I went to dinner at Mezzalira, a very nice Italian-based restaurant. Top notch stuff, I had a very nice roast bunny and the tagliatelle Bron ordered was the gold-standard of al dente.

For dessert, I decided to go for some cheese. On my last visit there, they had run out of the cheese I wanted to try. This time around, I ordered the full trio of cheeses.

And I’m glad I did.

GORGONZOLA DOLCE LATTE [LOMBARDY, ITALY]

A very good smelly cheese. I’m a big fan cheeses blue and pongy. The description on the menu said “on the palate the Gorgonzola has hints of mushroom” which was very true. Three-and-a-half stars.

The cheeses came with a weird little preserved-friut thing (apparently called Mostarda d’Uva). Kinda marmaladey. Went perfectly with this gorgonzola and my glass of port.

TALEGGIO [LOMBARDY, ITALY]

They grow this cheese in caves, I shit you not. Well, however they make it, it tasted damn fine. This is a “soft” cheese, and was very soft on the mouth, but didn’t run all gooey over the plate, either. And when you bite it, the rind has this wicked crunchy/crystally/salty texture, compared to the soft center. Very nice, 4 stars.

PECORINO SARDO [SARDEGNA, ITALY]

A pecorino is a little like a parmesan, but made by squeezing a bleater instead of a moo-er. As a hard cheese, it falls into my normal or “cheesy cheese” category, compared to the gooey or bluey above.

This is, hands down, the best cheesy cheese I’ve ever had. And even outside of its category, I can’t think of a cheese that I’ve enjoyed eating more.

It was hard enough to crumble slightly, but instead of being super-dry (like many pieces of old parmesan in my fridge) it was almost moist. It definitely had that classic salty taste, and had this great accompaniment aroma.

No question: 5 stars. Best. cheese. ever.

Getting Closure

(video)

Don’t be fooled by javac -target 1.4

In the last couple of weeks, I’ve been pinged a few times by cow orkers in the FishEye development team who were complaining about a mysterious JDK1.5 dependency in our code. Their development builds were breaking on a JDK1.4 JVM with an error like:

java.lang.NoSuchMethodError: java.lang.StringBuffer.append(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;

The sweat started pouring the first time I got that complaint; FishEye requires 1.4, we compile with -target 1.4 -source 1.4, and that method doesn’t exist in 1.4, it was added in 1.5.

Have production builds been going out like this?!

I knew the answer to that question was “no”, because we have a check like this in our Ant build (this uses some ant-contrib tasks):

<target name="check-prod-build">
    <propertyregex property="build.jdk.version" input="${java.version}" regexp="^(1\.\d).*" select="\1"/>
    <if><not><equals arg1="1.4" arg2="${build.jdk.version}"/></not>
        <then>
            <fail>Build aborting
====================================
A PROD BUILD REQUIRES JDK1.4.x ONLY!
====================================
You are using ${build.jdk.version} (${java.version}).
            </fail>
        </then>
    </if>

</target></pre>

Then the reason for putting that check in came back to me: because -target 1.4 -source 1.4 can still produce class files that won’t run under 1.4. How? Because neither of those options change what rt.jar you are linking against.

This is best illustrated with a little example. Take this simple file:

public class Test {
    public static void main(String[] args) {
    StringBuffer b = new StringBuffer("Hello, ");
    CharSequence s = "world!";
    b.append(s);
    }
}

When compiled with JDK1.4 it will run under both JDK1.4 and JDK1.5, but not when compiled under JDK1.5:

$ export JDK14_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.4/Home
$ export JDK15_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Home
$ $JDK14_HOME/bin/javac -target 1.4 -source 1.4 Test.java 
$ $JDK14_HOME/bin/java -cp . Test
$ $JDK15_HOME/bin/javac -target 1.4 -source 1.4 Test.java 
$ $JDK15_HOME/bin/java -cp . Test
$ $JDK14_HOME/bin/java -cp . Test
Exception in thread "main" java.lang.NoSuchMethodError: java.lang.StringBuffer.append(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;
        at Test.main(Test.java:5)

The culprit is the call to append(). In JDK1.4, the only call that matches is append(Object) and you end up with bytecode like:

invokevirtual   #6; //Method java/lang/StringBuffer.append:(Ljava/lang/Object;)Ljava/lang/StringBuffer;

But with JDK1.5’s rt.jar it matches append(CharSequence):

invokevirtual   #6; //Method java/lang/StringBuffer.append:(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;

Our Test.java is source-compatible with 1.4, the resulting Test.class as the correct class version for 1.4, but it is not link-compatible with 1.4 when compiled from 1.5. Have we learnt out lesson yet? Don’t be fooled by javac -target 1.4 -source 1.4: it can still produce class files that won’t run under 1.4.


Update Via Michael S and Chris N, you can also use the [code]-bootclasspath[/code], as described in the javac documentation.

All-knowing, but not all-subscribing

All great truths begin as blasphemies