Categories
Uncategorized

Using JavaRebel with Cocoon

Normally, the cocoon-maven-plugin includes a reloading classloader, so that changes to class files are automatically picked up when do mvn jetty:run. Just hit refresh and your changes get picked up. It’s just like working in PHP. 🙂

This is OK, but it’s not foolproof. This morning, I saw a few errors of the form “expected class SearchManager, but got class SearchManager”. This is a case of the same class being loaded by a different ClassLoader. Annoyingly, I can no longer reproduce this.

There’s a commercial product, JavaRebel, that aims to do a much better reloading ClassLoader. So, I thought I’d give it a try.

The basic idea to use it is twofold:

  • Include the javarebel jar as an agent.
  • Stop jetty from auto-reloading.

Of course, this being cocoon, we also have to stop the cocoon-maven-plugin from using its reloading classloader.

The javarebel documentation is quite clear on how to configure maven and jetty. But it makes no mention of cocoon (understandably).

Thankfully, it’s all fairly simple to configure with a maven profile. This makes it easy to call from the command line.

  
    javarebel
    
      
        
        
          org.mortbay.jetty
          maven-jetty-plugin
          
            0
          
        
        
        
          org.apache.cocoon
          cocoon-maven-plugin
          
            false
            false
          
        
      
    
  

With that in place, all that remains is a teeny-tiny shell script to augment the normal call to maven.

#!/bin/sh
javarebel_jar="$HOME/javarebel.jar"
MAVEN_OPTS="$MAVEN_OPTS -noverify -javaagent:$javarebel_jar" mvn -Pjavarebel "$@"

With this, you can immediately see that javarebel is enabled, as it spits out a big message at startup time. But more importantly, as soon as I change a spring bean (and reload the page that uses it), I get this on the console:

JavaRebel: Reloading class 'com.example.Spigot'.
JavaRebel-Spring: Reconfiguring bean 'spigot' [com.example.Spigot]

Hurrah — no errors! It all seems to work rather well. I should probably purchase a licence. 🙂

Update: I’ve seen the error again:

Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [com.example.MyService] to required type [com.example.MyService] for property ‘myService’; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [com.example.MyService] to required type [com.example.MyService] for property ‘myService’: no matching editors or conversion strategy found
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:104)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:59)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1198)
… 101 more

Categories
Uncategorized

Documenting with maven

Recently, I’ve been thinking about documentation more and more. I’ve just finished up some documentation for an internal product, which was all done using the maven-site-plugin and APT. This worked reasonably well: I get a generated website, with javadocs and a few howto pages I wrote.

But it really feels like it starts to fall apart when you get to a multimodule build. Maven does quite a few nice things for you, but you start to see some annoying glitches here. One of the first ones I came across was the url element. If you set it correctly in the root pom (e.g. http://mycompany.com/project/) then maven automatically appends the artifactId when constructing the site for submodules. So you end up with http://mycompany.com/project/mysubmodule/, which isn’t necessarily correct.

After thinking about this for a while, and how best to document jslint4java, I’ve come to the same realisation as Mark Pilgrim: plain old HTML works best. I’ve tried a few like Textile (yuck), Markdown (better), POD (too simple) and docbook (too complex). HTML strikes the right balance. Especially with the new HTML5 tags. And it doesn’t require any building to view it. Just hit refresh.

So how to make it part of the maven build? Easy. Stuff it into it’s own submodule. Then, it can be referenced by the assembly plugin later and put in the correct place in your distribution. Check out jslint4java-docs for details. It would be nice if maven natively supported zip packaging, but that’s easily overcome.

This does mean it doesn’t get automatically deployed to a server. But that doesn’t really matter. It happens infrequently enough that I’m happy to do that by hand where needed. Or at least find a better solution when I get bored of that. 🙂

Categories
Uncategorized

jslint4java 1.3.1

I’ve just released jslint4java 1.3.1. This is mostly thanks to Ari Shamash, who did an excellent job of telling me what needed to be done to get NetBeans to understand the output. The changes are small, but probably worth upgrading for if you’re using it.

  • Improved support for NetBeans thanks to Ari Shamash!
  • Correct line numbers (previously off by one).
  • The ant task now states the full path to the file being checked.
  • The build failure now includes the total number of errors found.
  • Updated to JSLint 2009-07-25.
Categories
Uncategorized

jslint4maven

A real maven plugin for jslint4java would be nice. I will write one, but until then, you can always get away with using the antrun plugin. This is fairly simple to do now that jslint4java is available in the central maven repository.

Here’s a plugin definition of how to do it.


  
    
      
        org.apache.maven.plugins
        maven-antrun-plugin
        1.3
        
          
            com.googlecode.jslint4java
            jslint4java-ant
            1.3
          
        
        
          
            jslint
            test
            
              run
            
            
              
                
                  
                  
                
              
            
          
        
      
    
  

Notice how you can add the jslint4java-ant dependency to the antrun plugin without affecting the dependencies of the project.

At the test phase, maven will now run jslint for you. This relies on a small external ant build file to actually perform the jslint task.



  
    
      
      
    
  

We can use the nice antlibs namespace style of declaration because the jslint4java jar is in the classpath already.

Here, I’m assuming that we’re in a war project and want to validate all the files under src/main/webapp. If this goes wrong, you’ll get an error and the build will stop. For example:

…
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0

[INFO] [antrun:run {execution: jslint}]
[INFO] Executing tasks

jslint:
[jsl:jslint] contact.js:1:8:Bad line breaking before '+'.
[jsl:jslint]         + " Nulla in felis Aliquam luctus Proin tincidunt nisi Donec suscipit"
[jsl:jslint]         ^
…
[jsl:jslint] load.js:17:6:Missing semicolon.
[jsl:jslint]     })
[jsl:jslint]       ^
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] An Ant BuildException has occured: The following error occurred while executing this line:
/Users/dom/work/someproj/jslint.xml:4: 3 files did not pass JSLint

One side note: originally, I tried to fold the jslint.xml file into the POM as well. But this failed to load the antlib. I suspect that xmlns attributes were not being passed in to the tasks definition. It’s not a big deal..

Categories
Uncategorized

jslint4java 1.3 post-release notes

These are the things I had to do after releasing.

Firstly, I needed to create a source archive as well as the main distribution archive. Git archive makes this super-easy.

$ git archive --format=zip --prefix='jslint4java-1.3/' rel-1.3 >jslint4java-1.3-src.zip

Secondly, I had to import the latest javadoc into svn at google code (it’s handy for linking to). I extracted this from the -dist.zip that got created as part of the release.

$ cd jslint4java-1.3/docs/apidocs
$ svn import --auto-props https://jslint4java.googlecode.com/svn/apidoc/1.3

Unfortunately, I had to then fix up all the damned properties anyway. I guess my svn config must need some attention.

Naturally, I forgot to update the version in NEWS.txt. Doh.

Categories
Uncategorized

Conditional maven modules

This is a little something that’s now caught me out a few times. Quite often, I’ll have a project with a parent POM, and a module that I only care about in certain circumstances. So I naturally do this.

  
  
    
      foo-core
      foo-webapp
    
    
      
        dist
        
          foo-dist
        
      
    
  

Unfortunately, this can interact badly with the release plugin. Unless that profile is activated during release, the module won’t have it’s version updated. So the next time you use that profile, it’ll break.

The correct solution is to “push down” the profile into the foo-dist module. i.e.

  
  
    foo
    foo-parent
    1.0-SNAPSHOT
    
      foo-core
      foo-webapp
      foo-dist
    
  

  
  
    foo-dist
    
      foo
      foo-parent
      1.0-SNAPSHOT
    
    
      
        dist
        
      
    
  

That way, foo-dist is always available, but is a noop unless the profile is activated. But it does ensure that the release plugin (and also the versions plugin) know that it’s there.

Categories
Uncategorized

jslint4java 1.3

I’ve finally released jslint4java 1.3. It’s available for download from google code.

The user visible improvements are few.

  • Better documentation.
  • The indent option is supported.
  • Add getEdition() call.
  • The ant task can now work with any kind of nested resource, not just files.
  • Updated to jslint 2009-07-08

I’ve moved the package names around. Everything is now in com.googlecode.jslint4java instead of net.happygiraffe.jslint. This will mainly affect ant users. The documentation should have some examples of the new form to copy.

The main change behind the scenes is that I’ve switched the build system to maven. This took me much longer than I expected. Though I’m still convinced maven is an effective tool, I can clearly see the rough edges. Still, now it’s done, it should enable more rapid releases in the future.

Categories
Uncategorized

Search & Replace in XSLT 2

For a project at $WORK, we want to implement Solr’s spelling suggestions. When you ask solr to provide suggestions, it comes back with something like this (the original search was spinish englosh):

  
    …
    
      
        
          1
          19
          26
          
            spanish
          
        
        
          1
          27
          34
          
            english
          
        
        
          1
          60
          67
          
            spanish
          
        
        …
      
    
  

What we want to do is transform this into:

Did you mean spanish english?

As it turns out, this is a non-trivial task in XSLT. It’s doable, but significantly easier in XSLT 2, since you are less restricted by the rules on result-tree-fragments.

The first problem to solve is getting the data into a sensible data structure for further processing. In a real language, I’d want a list of (from, to) pairs. In XSLT, sequences are always flat. The way to simulate this is to construct an element for the pair.

  
  
    
      
      
    
  

Note the commented caveat: we always pick the first suggestion for any given name. From my (small) experience, this isn’t an issue as the suggestions for a given word are always identical.

This results in $suggestions containing a sequence of elements looking like this.

  
  

Now one of the nice things about XSLT 2 is that you can define functions which are visible to XPath. So we can write a fairly simple recursive function to do the search and replace.

  
  
    
    
    
    
  

There are a few things to note:

  • You have to give your function a namespace prefix.
  • The xsl:param‘s are used in order (not by name) to specify the arity of the function.
  • The as attributes aren’t necessary, but the idea of types in XSLT is growing on me. I’d rather know about type problems as soon as possible.
  • The notion of cdr (tail) in XSLT is rather odd: the sequence of all nodes in the sequence whose position is greater than one.
  • Even though I’m using replace(), I’m not taking any precautions against escaping regex characters. I’m certain that these won’t occur given my data.

So finally, we end up with:

  
    
  
  

Did you mean ?

I don’t think all this will win any awards for elegance, but it does work. 🙂

Categories
Uncategorized

Solr’s Lucene Source

I’m debugging a plugin for Solr. I’ve just about got the magic voodoo set up so that I can make Eclipse talk to tomcat and stick breakpoints in and so on. But I’ve immediately run into a problem.

Even though Solr itself comes with -sources jars, the bundled copy of lucene that they’ve used doesn’t. Needless to say, this is a bit of a hindrance.

Thankfully, the apache people have set up git.apache.org, which makes this situation a lot less annoying than it could be.

First, I checked out copies of lucene & solr.

$ git clone git://git.apache.org/solr.git
$ git clone git://git.apache.org/lucene.git

Now, I need to go into solr and figure out which version of lucene is in use. Unfortunately, it’s not a released version, it’s a snapshot of the lucene trunk at a point in time.

$ cd …/solr
$ git branch -r
  origin/HEAD -> origin/trunk
  origin/branch-1.1
  origin/branch-1.2
  origin/branch-1.3
  origin/sandbox
  origin/solr-ruby-refactoring
  origin/tags/release-1.1.0
  origin/tags/release-1.2.0
  origin/tags/release-1.3.0
  origin/trunk
$ git whatchanged origin/tags/release-1.3.0 lib
…
commit 904e378b7b4fd18232f657c9daf484a3e63b272c
Author: Yonik Seeley 
Date:   Wed Sep 3 20:31:42 2008 +0000

    lucene update 2.4-dev r691741

    git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/branches/branch-1.3@691758 13f79535-47bb-0310-9956-ffa450edef68

:100644 100644 a297b74... 54442dc... M  lib/lucene-analyzers-2.4-dev.jar
:100644 100644 596625b... 5c6e003... M  lib/lucene-core-2.4-dev.jar
:100644 100644 db13718... f0f93a7... M  lib/lucene-highlighter-2.4-dev.jar
:100644 100644 50c8cb4... a599f43... M  lib/lucene-memory-2.4-dev.jar
:100644 100644 aef3fb8... 79feaef... M  lib/lucene-queries-2.4-dev.jar
:100644 100644 1c733b9... 440fa4e... M  lib/lucene-snowball-2.4-dev.jar
:100644 100644 0195fa2... b5ff08b... M  lib/lucene-spellchecker-2.4-dev.jar
…

So, the last change to lucene was taking a copy of r691741 of lucene’s trunk. So, lets go over there. And see what that looks like.

$ cd …/lucene
$ git log --grep=691741

Except that doesn’t return anything. Because there was no lucene commit at that revision in the original repository (it was something to do with geronimo). So we need to search backwards for the commit nearest to that revision. Thankfully, git svn includes the original subversion revision numbers of each commit.

$ cd …/lucene
$ git log | perl -lne 'if (m/git-svn-id:.*@(d+)/ && $1 <= 691741){print $1; exit}'
691694

So now we can go back and find the git commit id that corresponds.

$ cd …/lucene
$ git log --grep=691694
commit 71afff2cebd022fe63bdf2ec4b87aaa0cee41dc8
Author: Michael McCandless 
Date:   Wed Sep 3 17:34:29 2008 +0000

    LUCENE-1374: fix test case to close reader/writer in try/finally; add assert b!=null in RAMOutputStream.writeBytes (matches FSIndexOutput which hits NPE)

    git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@691694 13f79535-47bb-0310-9956-ffa450edef68

Hurrah! Now I can checkout the same version of Lucene that’s in Solr. But, probably more useful for Eclipse, is just to zip it up somewhere.

$ cd …/lucene
$ git archive --format=zip 71afff2 >/tmp/lucene-2.4-r691741.zip

Excellent. Now I can resume my debugging session. 🙂

NB: I could have just used subversion to check out the correct revision of Lucene. But, I find it quicker to use git to clone the repository, and I get the added benefit that I now have the whole lucene history available. So I can quickly see why something was changed.

Categories
Uncategorized

To XHTML or not to XHTML?

Today, we had a conversation about HTML 4 vs XHTML 1.0. For me, the matter was neatly settled they very first time I saw an XML system produce XHTML like this:

  

An article with an empty emphasis tag.

Perfectly legal XML, perfectly legal XHTML. But — if you serve up this XHTML as text/html (which 99.99% of the world does), then you end up with this:

Empty tags considered harmful

Why? Because it’s parsed as HTML. And the browser sees the start of an em tag, but no close.

And now I make sure that all our sites emit HTML 4. It’s a lot simpler.

This isn’t to say I don’t use XHTML. It’s a fine medium for further processing (e.g. applying XSLT). But it’s not right for serving up to browsers verbatim.