Craig Pardey Software developer, cyclist, parent

10Apr/100

Tapestry: UpdateComponents, Eventlistener and Script files

This week I encountered an interesting issue in Tapestry when I tried to dynamically load a component using Tapestry's built-in EventListener functionality. The component in question had a .script file associated with it, which Tapestry loaded dynamically, but the JavaScript functions in the .script file were "not found" when I tried to execute them.

After a bit of digging around, a colleague of mine noticed that Tapestry was loading the .script file using an eval() statement instead of inserting the script into the DOM.

In order for the JavaScript functions to be usable we had to change the script file to save anonymous functions into variable names.

Before:
function someFunctionName() {
...;
}

After:
someFunctionName = function() {
...;
}

25Mar/100

Eclipse can’t find source when remote debugging

I had a problem recently where Eclipse couldn't find my source files when remote debugging a particular application. It would stop and the breakpoint and show the class file with a "attach source" button, but pointing it to the source directory didn't do anything.

It turns out that the solution was to add the project to the remote debug configuration.

This is done by "Run -> Debug configurations..."
Choose the remote config from the tree on the left
Click on the "Source" tab
Click on the "Add..." button
Follow the wizard.

Hope this helps anyone with the same problem.

9Mar/100

Mercurial changes how you work

I've recently started using Mercurial, which is a distributed version control system.

DVCSs initially struck me as a solution looking for a problem. SubVersion seemed good enough for our purposes at work, but we decided to try out Mercurial for one iteration to see what all the fuss was about.

Perhaps the most significant difference between SubVersion and Mercurial is that Mercurial uses a local repository. This subtle distinction significantly changes how you work because you can commit your changes without having to publish them. A 'commit' in Mercurial is like a savepoint in database-speak - it gives you a safe place to roll back to if things go awry. Once you're happy with your changes you can use the patch queue to fold all your commits into a single changeset and 'push' (i.e. publish) your changes to the central repository.

With Mercurial I commit early and commit often.

26Feb/107

JRebel and Tapestry working together

I've recently started trialling JRebel at work. JRebel is a piece of software that hot-swaps your code so that changes made in your IDE are reflected in your application server without requiring a restart.

The benefits of this idea are fairly obvious. I no longer have to wait 1 - 2 minutes for JBoss to restart each time I correct a spelling mistake etc. The time saved by not restarting probably make the product worth the $US149 licensing fee.

Then there is the significant reduction in context switching. I no longer make a code change, restart JBoss, read the New York Times for 2 minutes, forget what I changed, then try to test it. Instead I make the change and test it straight away. This can only mean fewer bugs (and perhaps a less-informed developer but people assume that nerds live under rocks anyway, so that's ok).

Once JRebel was installed my JBoss startup time went from 1:40 to 3:45, but I figured that would be OK because I would only have to do that once a day. JRebel did most of what I expected it to, and I was happily coding away in my new no-context-switching life until I changed a Tapestry binding and the code wasn't hot-swapped even though I had the Tapestry plug-in enabled.

This forced a JBoss restart (or several, to be honest) and I had lost all the benefit of JRebel. Later I discovered that I needed to combine a few things to get JRebel to work nicely with Tapestry. Here's what I had to do:

  1. Enable the Tapestry 4 plugin (-Drebel.tapestry4_plugin=true)
  2. Enable Tapestry reset service (-Dorg.apache.tapestry.enable-reset-service=true)

Now whenever I change a Tapestry file, I simply invoke the Tapestry reset service (http://localhost:8080/myApp/app?service=reset) and then refresh the page. Voila! The code gets hot-swapped.

I think this technique works because invoking Tapestry's reset service clears its cache and forces it to reload the classes which have been updated by JRebel.