Thursday Mar 18, 2010

Java Posse Roundup


I've spending the week in beautiful Crested Butte, Colorado at the Java Posse Roundup. It's the fourth year in a row, with record attendance. And as always, it's been fantastic. It's hard to explain an Open Space conference - it doesn't sound like it would work, and I was personally surprised to see how well it worked when I attended the first time. Now I simply expect it, and it always delivers. One key reason why this open space conference works so well compared to say "unconference" events attached to major face-forward conferences is that you need to be away from everything and really immerse yourself - and here up in the Rockies we certainly are isolated!



The day before the conference started we had a "Languages Dojo" day where people pick different languages they're interested and go off building something. We had planned in advance to build a JavaFX version of the "Ohm Writer", a Zen-like text editor that is full screen, has nice relaxing background music, background sounds and typing sounds. We had a great time, and made a lot of progress. Unfortunately, we spent a lot of the day fighting with git (the version control system). I'm a very happy Mercurial user, but I've had a little bit of git-envy since I know it can combine local changesets into a single changeset to be pushed to the repository. I could see myself using that a lot. And setting things up on github for collaboration was very easy. But that's where the fun ended - nothing worked, simple merges aborted, error messages were completely unhelpful, and in general we repeatedly ended up checking out new clean workspaces and hand applying changes. I liked Mercurial before but now I appreciate it even more. (I hear the guys who were doing functional programming also were ripping their hair out with git. P.S. Joel Spolsky just posted a Mercurial tutorial).



The app is functional, and more importantly we made the editor start up immediately, load images and audio in the background and gradually fade in the image as soon as it's available. We also had difficulty playing the keyboard "click" sound until we realized you don't want to just repeatedly call play() on a media player -- you have to reset it -- either setting mediaPlayer.currentTime = 0s or calling mediaPlayer.playFromStart().



We also ran into another bug -- and this is a gotcha I've seen before, so it seems useful to highlight it here: For JavaFX Strings, null and "" are the same! Therefore, you don't want to write code like this:


while ((line = reader.readLine()) != null) {
// use line
}

because this will terminate the loop as soon as you reach an empty line!! Be very careful about checking for nulls explicitly when dealing with Strings.



We've also had Lightning Talks in the evenings. If you're not familiar with Lightning Talks, these are very quick presentations, one after the other, on any subject, but limited to 5 minutes. Yes, with a HARD 5 minute limit. The advantage of limiting the lightning talks to 5 minutes is that it forces the presenter to really focus on the interesting parts of the subject, and if it's really not interesting, at least you're only bored for a couple of minutes! The topics this year were really great though - there was even a fire-eating demonstration!
One way to keep track of the time is to use a countdown timer. We wrote one in JavaFX last year, which displays a classic countdown timer (imported Photoshop graphics) and a sound file playing as the timer is expiring. It's available as a webstart app if you want to run it for your own lightning talks, or you can study the code.






In addition to the morning open space conference sessions, the evening lightning talks, the progressive dinners, we've had some afternoon technical presentations and coding sessions -- check out our improvised projector screen in our living room:




Monday Mar 01, 2010

Using Mercurial over ssh without typing the password


We're using Mercurial. Our release engineering servers run web servers, so we can browse our repositories, just like the public NetBeans ones at http://hg.netbeans.org, and pull down new changesets anonymously. However, for authentication purposes, we also use ssh, so all pushes to the repository has to go through ssh.


$ cat .hg/hgrc
[paths]
default = http://our.server.sun.com/our/repository
default-push = ssh://our.server.sun.com//our/repository

(P.S. Notice how there are 2 slashes in the SSH path and only one in the http path - if you forget about that Bad Stuff(tm) happens.)



This means that whenever I pull (or determine incoming changes via hg incoming) it executes immediately, but whenever I want to push (or determine outgoing changes), I need to supply a password. And let's just say typing my password is not easy, since the password requirements at Sun (and shortly, Oracle) are really strict - no nice, short and simple passwords here!



I've been putting up with it for a year now - after all, it's just a couple of seconds here and a couple of seconds there - but I knew it should be possible to fix this, since back in my hardcore Solaris days I had all this stuff configured correctly via the ssh key agent so that I could ssh from one account to the next. On the other hand, I've googled it (mercurial + ssh) a couple of times, and the information I've found has always been for doing more complicated things (1,2) than the simple authentication setup I wanted. So I just put it off.



I decided to bite the bullet and look into configuring it - and it was really trivial. I'm bummed I haven't tried earlier! I thought I'd write this up in case it helps anyone else in a similar situation.



The reason it's trivial, is that it turns out there is nothing specific about using Mercurial here. This is actually a case where Googling something was harmful! If I had just tried it, instead of searching for a recipe and getting confused, I would have had this set up a long time ago! Hopefully this blog entry will help anyone searching for "hg ssh passwords" ! Anyway... You just need to ensure that you can ssh directly into the system you are trying to push to, and if you can do that, then mercurial can do the rest. And this setup is easy and well documented.



First, you need to generate a local key.


$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/tor/.ssh/id_rsa):
Created directory '/Users/tor/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/tor/.ssh/id_rsa.
Your public key has been saved in /Users/tor/.ssh/id_rsa.pub.
The key fingerprint is:
... (omitted) ...

Next you need to copy this file to the server and call it ~/.ssh/authorized_keys. Actually, that file may already exist and you really want to append to it, not replace it. So first ensure the directory exists:

$ ssh tor@our.server.sun.com mkdir -p .ssh
Password:

And finally copy your authentication key over to the server:

$ scp .ssh/id_rsa.pub tor@our.server.sun.com:.ssh/authorized_keys
Password:
id_rsa.pub 100% 422 0.4KB/s 00:00

That's it! Now try logging in again:

$ ssh tor@our.server.sun.com

On my Mac, this actually pops up the system authentication dialog:







Not only can I enter my password in the dialog, but I can tell it to remember this key in the keychain, and from now on, the system supplies the password to ssh when it wants to log in to hosts.

$ ssh tor@our.server.sun.com
Identity added: details omitted
Last login: Mon Mar 1 19:22:18 2010



And now, the whole point of this exercise -- I can run "hg out" and "hg push" (as well as scripts which operate over multiple mercurial repositories) without the need to type that annoying password again. On the other hand, how will I remember it now that I'm not repeating it like a mantra dozens of times per day?


$ hg out
comparing with ssh://our.server.sun.com//our/repository
searching for changes
no changes found



P.S. Here's a copy of my own authentication keys in case that helps you configure your own system. Please don't use these to log into our system.

Friday Dec 11, 2009

How to determine the JUnit 4 current test name


In my unit tests I often want to know the name of the test that is executing. For example, I often want to have the golden file (expected test output) computed automatically from the testname. As another example in my JavaFX testing, I often generate screenshots inside failing tests and it's useful to name these screenshots by the failing tests.



In JUnit 3 this was simple, since your testcases would extend a builtin JUnit class which had a method you could call to return the current test. However, with JUnit 4 that's no longer possible. I've googled and found the "correct" way to do it - using a special @RunWith to run the test class - but I find that solution unsatisfying. My utility methods which are invoked to read golden files and screenshot etc are in one place and I now have to decorate all my tests. Besides, I already have a @RunWith annotation on my tests because I want to run them on the event dispatch thread so I have a special test runner for that.



So, I've found a better way to do it. Better for me I mean - this may have problems and limitations I'm not aware of, but for all of my tests this worked wonderfully, and doesn't have the @RunWith requirements (though note that I don't do multithreading in my tests, other than invoke them on the event dispatch thread, so if you try to call this from a thread that didn't invoke the test it probably won't work):


public static String getTestName() {
// Try to find a method on the stack which is annotated with @Test -- if so, that's the one
StackTraceElement[] elements = new Throwable().fillInStackTrace().getStackTrace();
for (int i = 1; i < elements.length; i++) {
StackTraceElement element = elements[i];
try {
Class clz = Class.forName(element.getClassName());
Method method = clz.getMethod(element.getMethodName(), new Class[0]);
for (Annotation annotation : method.getAnnotations()) {
if (annotation.annotationType() == org.junit.Test.class) {
return element.getMethodName();
}
}
} catch (NoSuchMethodException ex) {
} catch (SecurityException ex) {
} catch (ClassNotFoundException classNotFoundException) {
}
}

// Just assuming it's the calling method
return elements[1].getMethodName();
}


As with most of my test utilities, it's a public static method living in a class called TestUtils, which I statically import from my test cases such that I can simply reference the test name getter like I would in the JUnit 3 days:

import static org.junit.Assert.\*;
import static my.package.name.TestUtils.\*;

/\* ... \*/

screenshot(scene, getTestName());


By the way if you're using JavaFX you might be interested in the screenshot utility method. It's really simple:

public static File screenshot(Scene scene, String fileName) throws Exception {
BufferedImage image = (BufferedImage) scene.renderToImage(null);
if (!fileName.endsWith(".png")) {
fileName = fileName + ".png";
}
File file = new File(getScreenshotDir(), fileName);
file.createNewFile();
ImageIO.write(image, "png", file);
return file;
}

(where obviously getScreenshotDir() returns a File folder where you want your screenshots generated. A decent default implementation is return new File(System.getProperty("java.io.tmpdir")); ...)

Sunday Nov 08, 2009

JavaFX Coding Conventions


I've been writing a lot of JavaFX code over the last year. After some tweaking I've arrived at a style that I like a lot. I notice that even on my team there are some variations in how people format their code, so I thought I would document what I like in case this helps others get started. (I did a quick google search and didn't find any JavaFX coding convention documents anywhere. The closest thing I found was a blog entry, but while it contains a lot of good advice, the style it recommends does not match the practice of the JavaFX team (or the Sun Java style) either). Therefore, I thought I would document what I consider good JavaFX coding conventions.



Rather than post them here in a blog entry, I placed them in a Wiki page such that they can easily be improved and kept up to date as I get feedback and in case I change my mind :)



You can find the coding conventions document here:


http://wikis.sun.com/display/JavaFxCodeConv/Home



P.S. I will be speaking at Devoxx in Antwerp, Belgium next week! Hope to meet some of you there!

Tuesday Jul 28, 2009

NetBeans 6.7.1 is out - with JavaFX 1.2 support


NetBeans 6.7.1 was released yesterday, which in addition to a number of important bug fixes in various areas, also now includes support for JavaFX.



It looks very promising; the biggest problems I mentioned a couple of months ago are fixed. I no longer get any bogus or stale error messages. And the preview pane seems to work - I'm not getting exceptions left and right. Also, the preview panel is docked into the navigator area - that seems like a good place for it.



Code completion and import management works as before - which means it might be a little surprising (see my old blog entry for tips), but it works.



Unfortunately, my two other pet peeves are still there: No toggle comment, and no mark occurrences jumping - which is extra problematic since there's no Find Usages for the JavaFX support. I took a quick peek at the sources, and adding it is trivial - so I submitted a patch.



In the meantime, you can download this .nbm plugin file and install it via Tools > Plugins if you want to get these two features. Cmd-/ to toggle comments, and Ctrl-Up/Down to jump between the occurrences in the current file. Note that I couldn't create a separate plugin to do this - I hacked the existing JavaFX editor support. That's because the mark occurrences feature needs to access a method which is package private (and I didn't want to mess around with reflection - I can't spent time on this). This unfortunately means though that you are using a hacked version of the FX editor module. If they release patch updates later you'll be replacing this functionality. But hopefully by then they will have applied the patch!



I noticed by the way that all the source code for the NetBeans JavaFX plugin is available right there in the public NetBeans Mercurial repository - so you can not only grab the source code and build it yourself, but you can fix and contribute patches to make the support better. I want a good JavaFX source formatter! Actually I'll even settle for just a simple indenter. Please, pretty please? P.S. I see that there is already a code formatter class in there - I added a breakpoint and stepped through it a bit but I couldn't see anything obvious, and I unfortunately can't spend any time on this, so hopefully somebody else can step up to the plate?




Monday Jul 06, 2009

Back from Vacation


I'm back from a nice but short vacation. We didn't have a detailed itinerary - we just took one day at a time and decided where to head next. We spent several days in the old Gold Rush country in the Sierra foothills - there were many things to see, such as museums, mines and caverns, and a preserved whole gold rush town with original buildings, a no-cars main road and all employees wearing authentic clothing. From there we visited the central coast and went to several of the original Missions, and ended up seeing the 4th of July fireworks from the beach in Santa Barbara. While I was gone I see that NetBeans 6.7, and Virtual Box 3.0 have both been released. Both should help me as I get back to work...




Wednesday Jun 17, 2009

New iPhone software - now with podcast speedup



The new iPhone 3.0 software was released a little under an hour ago. The upgrade was trivial. I clicked the Check For Update a few minutes after the release, and it downloaded the new OS in around 3 minutes! I recently switched ISPs so I have really good bandwidth now - but I had expected a lot of traffic on Apple's servers to slow things down.



The update looks really good. I tested a few of the things I have been looking forward to -- I personally don't care about the feature highlights listed on most sites, such as MMS, Copy and Paste, etc.



The first feature I've been waiting for is the ability in the browser to open a link in another window. With tabbed browsing I'm used to just ctrl-clicking on links such that pages load in the background, and when I'm done with the current page I go read the other tabs which by then are fully loaded. On the iPhone on the other hand I haven't been able to do this, since there hasn't been a way to open a link without throwing away the page you're on. But in 3.0, it's there - just click and hold a link and you get the option to open the link in a new page. It's not as good as tabbed browsing - it instantly jumps to the new, not yet loaded page, but it's trivial to jump back and keep reading while the new page is loading.



The second feature I've been waiting for is improved iPod controls. The primary usage for my iPhone is as an iPod - while running, doing chores or driving - and I listen to a lot of podcasts. With 3.0, the scrubbing feature is improved - it's now a lot easier to jump to arbitrary points in the podcast. I like to listen to This Week in Technology for example, but I'm getting really, REALLY sick of the 5+ minutes of Audible commercials in each and every episode. This is the DVR generation -- if a commercial is longer than 30 seconds I'm going to start resenting you. In 2.0 it was difficult to either fast forward (too slow, then too fast) or jump to arbitrary points in the podcast. With 3.0 it works really well - I just place my thumb on the scrollbar and lean it to the right then left to tweak the final endpoint.



Another iPod improvement is the ability to play podcasts at a faster rate. For the Java Posse some volunteers (thank you!) set up a server which would download our podcasts, apply audio processing to speed up the podcast, and then release these as faster versions of our episodes - called the Tempo Posse. This is no longer necessary with 3.0 - there's a button you can click to cycle between half speed, full speed and double speed playback:







I don't think this will run the Tempo Posse out of "business", because I looked at our download stats the other day and nearly half of all episodes are downloaded outside of iTunes! Are there really that many Zune users? ;-)

Tuesday Jun 16, 2009

Code Advice #16: Don't Encode Symbol Type in Variable Names!


(See intro for a background and caveats on these coding advice blog entries.)



I came across a JavaWorld coding-advice article the other day. While the thread which led me there referenced the second point of the article, I couldn't get past the first one where the author argues that


...a reader needs to know which items are local variables, which are fields, and which are method arguments. [...] It's likely best to use a simple naming convention to distinguish between these three cases.




I couldn't disagree more!



His key argument seems to be that when you are reading code, it's important to know whether something is a field since when you read a method, you might suddenly see a reference to something you haven't seen before. To make his point he shows this graphic:







His improved version is here:







I have a couple of problems with this.



First of all, why encode this information in the symbol name when IDEs will show this information automatically? NetBeans will show fields in greens, and statics in italics - and it will always be right, whereas the code might lie. Just like comments can get out of sync with reality, you could inline a field without remembering to change its name (especially if another developer did it without realizing the meaning of the variable prefix). Or if you get in the habit of seeing an "f" prefix as meaning field, what about local variables that legitimately should start with an f, such as "focus" ? Sure, the second variable should be capitalized, but what about typographically similar symbols like lowercase l and uppercase I?



Here's how the same function looks in NetBeans:







In addition to showing us the fields in clear green, the IDE also pointed out that this method is overriding another method (I hovered over the overrides glyph in the editor margin). The yellow line is warning us that this override doesn't have an @Override explicit annotation on it.
Information about overrides is just as important as whether an identifier is a field.



Highlighting fields in green isn't specific to Java... We do this for many other languages - see some screenshots of
Ruby, PHP, Groovy, etc.



Here's a snippet of JavaScript - notice how we have a reference to a global variable in there shown in green:






The key point here is that you shouldn't write your code to target reading code in black and white on paper. You shouldn't print out your code at all! Reading code with an IDE lets you easily check any condition you encounter (and just like in a browser there is a little go-back icon in the editor toolbar which maintains a visit stack so you can easily pursue multiple ctrl-clicks to track something down and then easily go back).



There are some other conventions left over from the days of code written on tiny terminals and printed out on paper for review - such as the "maximum 72 characters per line" limit. There's no reason for that when using modern tools. If the code is more readable unwrapped at 100 characters, leave it that way rather than introduce arbitrary breaks in the middle. (Having said that, don't take this as an endorsement to write deeply nested methods, that's a sign of poorly thought out design.)


My second objection to the article is that it is not clear to me that knowing whether something is a field or not is the critical piece of information you need. I think the following questions are probably more important:


  • What is the meaning of the variable, and what is the intended use?
  • Can it be null? Can it be negative?
  • What is its type?
  • Where else is it referenced?

And so on. Just prepending an "f" on a field reduces readability in order to avoid a simple lookup, when I believe you in general
need to know more context anyway.
And again, a tool can help you here. In NetBeans, hold down the Ctrl key (Command on the Mac) and hover over a symbol and you get help like
this:







(As a side note: I heard that at a Scala talk in JavaOne, Bill Venners was showing NetBeans through most of his talk, but he switched
to Eclipse to show one feature: Pointing at symbols show the actual inferred types of scala identifiers. Scala is as you know a statically
typed language, but uses a lot of type inference so the types aren't obvious from looking at the source. That's a very useful feature,
and I thought I'd point out that NetBeans has this feature too -- using the exact same mechanism as the above; just hold the Cmd/Ctrl key
and hover over a symbol, and you will see its type.)



Finally, the article makes a point that you probably want to distinguish parameters as well. I agree with that, but again not by changing
the name of the parameters, but through color identification. In Ruby, JavaScript, Python etc. we do that automatically in NetBeans - parameters are orange by default. For Java, it's not enabled by default (at one point it was, but somebody determined that the source code just looked too colorful, so the default color scheme was dialed back. I was working on Ruby at the time so my colors flew under the radar... and
all GSF-based languages such as JavaScript, Python, Scala etc. now inherit that color scheme...)



You can turn this on for Java as well. Just open the preferences, and for Fonts and Colors choose the Java language, then customize the Parameter Use and Parameter Declaration values:







Some languages like Ruby use sigils, where fields start with @, globals with $, symbols with : and so on. I don't have a problem with that
since I don't think these are as obtrusive as -letters- in variable names.



If you are reading code on paper, or with an editor that doesn't support semantic highlighting, you are voluntarily handicapping yourself.


Monday Jun 08, 2009

The Authoring Tool


We lifted the veil on the new designer tool for JavaFX last week at the JavaOne 2009 conference. Here's a screenshot:







The tool made a number of appearances:


  • First in the Tuesday keynote where my boss Nandini showed the basics of the tool.
    Video,
    starts at 23:08.

  • Then in the mobile keynote where Eric Klein showed the multiscreen support and mobile deployment.
    Video,
    starts at the beginning.

  • And finally in the Friday keynote where I got to do a longer 10 minute segment on the tool.
    Video,
    starts at 10:25.

The above video links just point to small chapters of each keynote; for full video replay go to
the keynote replay page.



I've scanned the blogosphere and twitter for comments on the tool and demos and the feedback is very positive.
Here's
a particularly detailed blog post with pictures and video snippets detailing the Friday demo.
Now we just need to finish the feature set, fix the bugs and polish everything! It's been a sprint for the whole team to get to this point. But we're not building a demo! We're building a product! So we're not getting much of a rest, it's right back to work to finish this thing!








(Photo by Balz Schreier)



P.S. In case you missed it, Larry Ellison from Oracle went on stage and made several comments regarding JavaFX in case the acquisition should happen - here's one article, there are many others.



P.S.2. We had our fourth annual Java Posse BOF live recording session last week. It was a blast. Dick stayed up editing and releasing
the podcast
the same night. If you're wondering what happened in the middle of the episode, where there's not much audio and a lot of laughing, that's me nearly drowning. I took a big swig of beer just as Joe made a joke; the beer went down the wrong tube, and then I was laughing so hard I couldn't breathe. My eyes were runny and I had beer all over my face and chest. Pretty embarrassing but reportedly also entertaining for others! Here's a photo from our get-together at a bar afterwards:







(Photo by
Toni Epple)

Thursday May 14, 2009

Run Tests - Without Focus Loss!


I like unit tests - but running them can be painful. Commit-validation tests
which bring up UI are obviously annoying, but even simple unit tests that
get in the way. Does this look familiar?







The above menubar should look familiar to anyone on a Mac who's run unit tests for client side
Java code. Not necessarily GUI tests, just any test where GUI libraries are loaded.



For every testcase, the test runner fires up a new process, which tells
OSX that "I'm graphical, give me focus!", and this steals the focus from the user.
The test finishes quickly thereafter, the process quits - and then the test runner
goes to the next test and the whole cycle starts over.



This is really painful because I like to have lots of tests. The Python editor support
for Netbeans had 600+ tests;
the counts for the JavaScript support was higher, and
the Ruby support even higher than that. Whenever I run tests, I basically have to
fight with my computer to get focus. Forget trying to write anything - every second
or so my keystrokes get stolen as the next test grabs focus - so I've gotten in
the habit of using the time for browsing, since I'm mostly reading, and I can handle
clicking a link a second time if the first click got lost. But every now and then
somebody will ping me on instant messaging - and it's maddening trying to respond while
this is going on.



If this is sounding painfully familiar to you, I have good news. I've finally figured
out a setup where this is no longer a problem!



The key discovery was that I can run my tests from another account on the system.
With OSX' fast user switching, I can switch to the alternate account, launch the
unit tests, and return back to my regular account where the tests won't interfere
with display focus. In order to let me run my tests from that other account, I
just open a terminal there and su -l tor in the shell to run all the
commands (or NetBeans) as myself.






This was a huge improvement since it removes the 10-30 minutes testrun downtime.
But it had some disadvantages - first, I don't like running tests from a shell, and second,
it's hard to know when things finish - and switching back and forth to check is annoying
since I always have passwords on my accounts so the machine isn't open.



So the second step was to set up Hudson (a
continuous integration server that is trivial to setup, and has a huge number of
plugins which makes
graphing code coverage, unit tests, findbugs results, integrating with version control
systems etc trivial. And it's
not just for Java developers
.)



Instead of logging into the other account
for each test run, I log into the other account once, and start up Glassfish
with Hudson running. From now on I can access, configure and launch builds right
from my own browser in my primary account. The key step here is that Glassfish was
started from the secondary account, so its primary display is associated with the builder account.
When my build in Glassfish gets to the test stage, it's actually doing the display
connection just as before, and if I log into the secondary account, I get the annoying
focus flashing just as before. Look - the tested process is a user visible application in the dock:






Another improvement which really helped is the "File System" version control plugin for Hudson.
I want my Hudson builds to build my current working copy. I don't want to
check my code into Mercurial (even a local repository) just so that Hudson can
grab the code and build it. I want Hudson to build my current changes - my current
edits. After all, I'm trying to test them before checking in! And I discovered that
there is a plugin which will let me do that - it's just
a "file system" version control wrapper - which means you just point Hudson to your local
directory, and off it goes. When the build starts, it makes a quick disk-copy of the
source tree. Even though Mercurial cloning is pretty fast, this is even faster.
The disk copy also lets me specify a filter of files to exclude, so I had it ignore
\*.class files. The diskcopy only takes 10 seconds or so before the build kicks
off, and it's building a snapshot of my current in-progress, edited working copy!
(It can also just update the copy based on changed filestamps - that's even faster,
but it didn't seem to correctly delete removed files, so I let it start from scratch
each time.)







(Note - this plugin isn't in the catalog that you can browse right from within the
Manage Plugins page within Hudson; I downloaded the .hpi file from
http://wiki.hudson-ci.org/display/HUDSON/File+System+SCM
and installed it in the Advanced tab.)



The final ingredient is the new Hudson support in NetBeans 6.7. I don't even have
to go to the browser to kick off build jobs. I just point NetBeans to my Hudson
server once, and from then on I have full Hudson integration. When I want to
run my tests I just select Launch job:







I get notified if there's a problem:







I can look at failures and logs:







I can see build logs etc. directly in the output window, and hyperlinks warp to directly to files - to the files as they were in the build, not the current state:






So to recap - with this setup, as I'm editing my code and I want to check the tests,
I just right click on a node and say "Start Job" - and off it goes without bothering
me at all - no more focus interruptions, and no more GUI windows popping up from
interactive tests. It's trivial to check the results. And it's even added one more
level of convenience: I have multiple projects, each with unit tests, and from the
IDE I couldn't have them all run with a single gesture. My build job does that.



I'm really stoked! I was at one point able to do this when I was working on Linux
and Solaris by setting my $DISPLAY variable and doing tricks with VNC. But that
still required my tests to run in a console - which made interpreting the results sucky.



If you haven't played with Hudson, try it - it's unbelievably easy to set up. Just download
the Glassfish appserver and install it, download the Hudson .war file, and drop the hudson.war
into the autodeploy directory of the appserver, and browse to localhost:8080/hudson.
Once you're there you can install
plugins (under Manage hudson), point to your local installations of the JDK, ant,
etc., and configure your build jobs by running scripts, launching maven scripts, writing
ruby scripts, or obviously running ant scripts.



Some final miscellaneous tips:


  1. I don't want Time Machine to back up my builds trees, or Spotlight to
    index data in these directories, so I went to the TimeMachine preferences and had it
    exclude the ~/.hudson/jobs/ directory.



  2. I did the same thing for Spotlight - but unlike
    the Time Machine preferences, there was no checkbox to "Display Invisible Files" (e.g.
    files that start with a dot, such as .hudson) in its file chooser. Here's a tip I didn't
    learn until recently: When a Mac filechooser has focus, you can press slash (/) - and this
    will open a text field where you can directly type the path it should jump to. I typed
    /Users/tor/.hudson and from there I was able to select the jobs directory to exclude.



  3. You might be tempted to skip the "filesystem version control" plugin and just have
    your build symlink to your working copy. Be careful; if Hudson is configured to delete
    older builds you might find yourself without your source code. I'm not saying it will
    follow your symlinks - Java has support for symlinks now - but I haven't tried it, and
    I have been bitten by ant in the past where it decided to follow symlinks in its
    zeal to delete recursively!




  4. I recently discovered that you can reorder the build steps in a Hudson job. The little
    graphic to the left of a build task is a handle you can just drag to reorder!






Tuesday May 12, 2009

...at least my house didn't burn down!


As I was working yesterday my laptop felt kinda wobbly. I didn't think too much about it. But it started getting annoying. I lifted the laptop and looked under it to make sure my laptop wasn't accidentally sitting on top of a USB cable or something like that. Nope.



A little while later I was getting really annoyed - so I flipped the computer all the over to see what was up. And to my surprise my battery was completely warped. It looks like it had "exploded" sometime this weekend. Check out how warped it is:






A couple of years ago one of my Apple power supplies would make humming noices now and then, and one day I happened to be looking at it when it shot some sparks! Luckily I had a floor mat so any previous sparks hadn't ignited the carpet. I got that adapter replaced. But I'm definitely thankful neither incident caused fires!

Wednesday Apr 29, 2009

JavaFX editing tips!


The NetBeans support for editing JavaFX isn't as mature as for other languages. After working with it for a little bit I've figured out a few things you might find helpful:



  • One thing I do a lot when experimenting with FX is trying to comment out parts of the scenegraph to try different things.
    The way I comment/uncomment
    in NetBeans is using the Toggle Comment action -- Ctrl-/ or Cmd-/ depending on your platform. But in JavaFX that keystroke does nothing!
    It turns out they have implemented Comment and Uncomment, just not toggle. So you can just use those actions instead (they're in
    the editor toolbar on the right.)



    Or, if you're like me, you really want Toggle Comment. Especially because it has a keybinding. In that case you can install
    this plugin which adds toggle comment
    support for .fx files. It's a trivial module (just two small files (1,2)) so I'm hoping this will be
    included in the next version.



  • The second issue I ran into is that the editor sometimes tells me my source code is wrong - and I'll stare at it without figuring out
    the problem. Turns out - I'm often right. The code is okay, and the background parser is confused. At the
    roundup a number of other people ran into this bug.



    Fortunately, there's a simple workaround for this - just select all (Ctrl-A), hit delete to wipe the file clean,
    and then undo (Ctrl-Z). You'll get your source
    file back, and the file should be (re)parsed correctly. It looks like there is some kind of incremental parsing bug. If you disagree
    with what the IDE error message is telling you, go ahead and try this workaround.



    Here's an example. The editor is telling me I have an invalid assignment -- huh? There's no assignment there!







    If I select all, delete, paste, I get this - all better:







    An annoying bug, but once you know about it it's pretty trivial to work around it.



  • At first I thought code completion was really broken. Let's say I wanted to insert a DropShadow. Not knowing
    where it lives I would just type DropS to get NetBeans to show it to me and also import it for me (and advantage
    of using code completion instead of just typing the name). But that just didn't work - after typing DropShadow and
    attempting code completion it wouldn't show me any matches!



    Turns out there's another workaround for this. Just hit Ctrl-Space again! In the Java editor, we distinguish between
    completing only the imported classes and all available classes. If you for example have imported a class named "Video"
    in your class and you code complete on "V", it will not list "Vector" as a match (unless that class is also already imported) -
    it will only show the imported classes that match the V prefix. If you press Ctrl-Space a second time, you get to see all
    V matches. Of course, the code completion dialog tells you this - it says "Imported Items; Press Ctrl-Space Again for All Items" right
    there in the list.



    However, this never seems to bite me when coding Java, because it does something else: If there is no match, it will proceed to do
    the all-items completion on its own - so most people don't have to think about it. The JavaFX editor on the other hand does not do this
    so you end up typing a prefix you know exist, complete, and - nothing.







    The workaround is simple - just press Ctrl-Space a second time when this happens, and voila - the class shows up and gets imported
    as well. Of course - the message at the bottom of the semi-empty code completion window says as much, but since you don't usually
    have to pay attention to this in Java (because it auto imports when there isn't a prefix match) you might have missed it:







  • Import Management. At first I would try to just type "DropShadow { }" - and the editor would complain that it doesn't
    know what I'm talking about. Alt-Shift-i, which imports the symbol under the caret doesn't do anything.
    But it turns out that Cmd-Shift-i, Fix All Imports, DOES work. So use that one instead. It doesn't give you the dialog
    you get in Java showing all the matches; instead it works its way sequentially through all missing symbols.







    P.S. Fix Imports also cleans up unused imports.



  • The Preview Panel seems to be a bit hit or miss. I loved using it, but I would occasionally get lots of exceptions from it,
    so now I only use it for simple scenegraph experiments and tend to just run instead to test stuff - it's been fast enough.



  • The main thing I'm missing is keyboard navigation among occurrences. As you (hopefully) know, Ctrl-Up and Ctrl-Down lets you
    cycle through the yellow occurrences of a symbol when you're editing Java, JavaScript, Ruby, etc. This is really handy since
    it gives you instant "find usages" within a file - just click on a symbol and ctrl-down to cycle through the references.
    JavaFX has mark occurrences - but unfortunately they're missing the small code to iterate this through the keyboard.
    I thought I could just add that trivially along with the toggle-comment code plugin above, but unlike toggle comment which
    took 3 minutes to write, I couldn't see a simple (30 minutes or less) way to get access to the occurrences highlights from
    the outside, so I instead fired
    off an e-mail to the FX editor team - I'm crossing my fingers that they can get this in the next version!




Monday Apr 27, 2009

Nice touch, Skype!


I work from home, so I rely heavily on Instant Messaging and IRC to communicate with my co-workers, and for video conferencing I use Skype.



I sometimes make typing mistakes. And if the typo is particularly embarrassing, to the extent that I want to fix it to show that I know better,
I usually write something like this:


12:00 I agre.
12:00 s/agre/agree/

Anybody with vi experience or even sed experience will recognize the second line as a search/replace command, so I'm really saying "I said agre but I meant agree". It's reflex at this point - I'll do it for the most minor accident.



I usually only use Skype for video conferencing, not instant messaging. But I just discovered, by accident, that Skype does something wonderful. Instead of showing my substitution command, it applies it to the previous line, instantly, on both sides of the conversation! Look at this:







Ugh, typo, reflexively type s/foo/bar







Voila:







Instead of adding my correction command to the log for the viewer to interpret, it just edited the previous command in place. If I can type this quickly enough, perhaps the reader won't notice!



Chatzilla, Adium, Others - Please please please do this too!



P.S. On the topic of terminal conventions.... I like using \^H's as a "just kidding" device:


12:00 Ok, I'll slap\^H\^H\^H\^H tell him about it.

Anyone who's logged into terminals with wrong tty settings will recognize the \^H's as failed backspaces... And I don't want IM clients processing these :)

Friday Apr 24, 2009

Catchup


A lot of stuff is happening these days, so here are some quickies... is this what people use Twitter for?

  • My brother is visiting me these days. He's in town for the MySQL conference, where he presented his work on memcached. He's also a huge fan of Solaris, so I'm now running OpenSolaris on my desktop machine. It's fun to see how user friendly the (always powerful) operating system has gotten. And his blog entries like this and this take me back to my first job at Sun - working on the Solaris debugger UI. Good memories.





  • Yesterday was "Take Your Daughters and Sons to Work Day", so I brought my kids down to the Santa Clara campus. They had a great time. After "working" in an office while I was on my laptop, we walked around the campus, they met my boss, and I'm sure the highlight for them was having lunch in the Sun cafeteria - which even had a special kids menu for the day. In our walk through some of the buildings we came across a pool table where they got to try pool for the first time.



  • I had the honor of being interviewed on the PlanetCast a week or two ago. That's the third episode of the podcast, but do yourself a favor and listen to the first two - with John Rose on the DaVinci Machine Project, and James Gosling on Java and JavaFX. I've had to drive down to the Valley almost every day the last couple of weeks for meetings, so the timing of my discovery of the PlanetCast couldn't have been better!






  • My friend Carl Quinn just got his Tesla - an all electric super sporty car. He's waited two years or so since he ordered it and they're just now coming off the assembly line. When we got together for a podcast recording session Wednesday night he brought the car, and took each of us for a spin around the block. Wow! It felt like like getting a ride in a fighter jet - but while the acceleration force was amazing, unlike a jet the all electric motor is unbelievably silent. I can't wait for cars like these to get to mass market! There are some pictures of our rides on Jackie's blog, and Joe has a lot more pictures and even some video.


  • The Ruby support in NetBeans 6.7 is coming along nicely. Erno just announced that preliminary Ruby 1.9 support is in the builds now. More details on that in his blog entry. And in another blog entry he's describing work he and Martin did recently to improve the type inference support in NetBeans. Here's some Ruby 1.9 goodness:






  • Finally, we're using JIRA as the issue tracker for the JavaFX project, so I've been using Cubeon for NetBeans a lot recently to handle querying and updating issues from within the IDE. I don't have Eclipse envy, but I'm impressed by their Mylyn project which looks both nice and useful, so I definitely welcome task oriented flow into NetBeans as well. In addition to connecting to repositories like Bugzilla, JIRA and Trac, Cubeon adds some basic support for tasks (e.g. when you "activate" one task, all breakpoints you set in the debugger get grouped and associated with this task and so on), so I'll be playing more with that. I'm using a daily snapshot rather than the most recent published version, and I'm pretty happy with it. I'll probably have more to say about this in another blog entry as I get more experience with it.









Tuesday Apr 07, 2009

Add Effects to the right Container!


The Flubber application I described earlier has an old stop-watch style timer with second and minute hands:







Making the clock hand move was trivial using value binding and a rotation transform on the hand graphics object:


transforms: Rotate {
angle: bind (360.0 / 60 \* minutes) - 90.0
}

Since we are using a binding expression, setting the minutes variable anywhere (and yes, assigning to it!) will cause the hand angle to be recomputed and the graphics updated.



Anyway - once we had the clock moving, the first thing we wanted to do was improve the look of the clock by adding a drop
shadow. That was trivial; all we had to add was this:


effect: DropShadow {
offsetX: 5
offsetY: 5
color: Color.BLACK
radius: 10
}

That looked pretty good:






But look what happened when we let the timer run... Where is the light source?






What's happening here is that the drop shadow is rotating with the hand. Not what we want.
We were all learning JavaFX that day, so we hacked it, using the following code:


effect: DropShadow {
offsetX: bind Math.sin(Math.toRadians(handAngle + 45)) \* 5.0
offsetY: bind Math.cos(Math.toRadians(handAngle + 45)) \* 5.0
color: Color.BLACK
radius: 10
}

Now, the drop shadow offset moves along with the rotation such that the shadow always appears in the right place.
It worked, and we moved on.



Now that I understand JavaFX and the scenegraph a bit better I realize that this approach is wrong - there's a much simpler solution!
We don't want to apply the drop shadow to the Path object directly, since the path is what we are rotating with our minute angle.
Instead, we should simply move the effect out to the surrounding parent. That will apply the drop shadow after the shape
has been rotated.
Doing that, we can set our drop shadow initialization back to the original simple 5,5 delta, and we get exactly the result we want:







So, think about which node you apply effects to! And by the way, the effects framework is really fun to play with - you should definitely
explore javafx.scene.effect.\* !

About

Tor Norbye

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today