20051030 Sunday October 30, 2005

On the stability of four feet tables

While I was digging up some information about influenza in Europe (my entire family, including myself have been sick for some days), I ran into this publication. The author prooves that any four-feet table can be put into a stable position by simply rotating it. Don't ask what this has to do with influenza. I find this an amazing discovery; it's just so simple, that I would never have expected that it could be proven mathematically.

You can read more about this in Nature online (http://www.nature.com/news/2005/051024/full/051024-3.html) This is the abstract of the original publication, following by an excerpt of the introduction.

"We prove that a perfect four-feet square table, posed in a continuous irregular ground with a local slope of at most 15 degrees can be put in equilibrium on the ground by a “rotation” of less than 90 degrees. We also discuss the case of non-square tables and make the conjecture that equilibrium can be found if the four feet are on a circle."
"Anybody eating lunch or drinking coffee at the terrasse of the CERN cafeteria has had the following problem. Most of the time the table is not in a stable equilibrium position. It rests on 3 feet and with very little energy it can be made to oscillate so that part of your coffee is spilled at best on the saucer or worse on the table. Why is this? Not because the table is not well built but because the ground is very irregular. Many years ago I thought about this problem, and in a relatively idealized situation I proved that by “rotating” the table (“rotating” is to be explained later) one could find an equilibrium position if the local slope is less than 15 degrees. In practice I did many times the experiment outside the CERN cafeteria, and even though the conditions of the theorem are not really satisfied - the feet are thick, the ground is sometimes discontinuous, but on the other hand, the legs of the tables have some elasticity - I have always succeeded in finding an equilibrium position. I think that my early sketch of a proof dates back from 1995. I presented a tentatively “serious” (but partly incorrect ) proof in 1998 at a seminar at I.H.E.S. in Bures Sur Yvette but it was never written for some serious personal reason."
( Oct 30 2005, 12:00:00 AM CEST ) Permalink Comments [0]
20051025 Tuesday October 25, 2005

Customizing Maven 2 Site Layout

I consider the release of Maven 2 to be both good news and bad news. The good news is that it is just very good stuff. It's fast. It's simple. It's just so much better than Maven 1. The bad news is that I had done a lot of work in Maven 1, which I now need to port to Maven 2; I can no longer hide behind the fact that Maven 2 has not been released...

One of the things that I have on the roadmap for porting it to Maven 2 is a customization of the site rendering mechanism. This allowed us to have a Sun branded site layout, like shown below. The old mechanism was based on something calle JSL - a Jelly based implementation of XSLT. If you ever feel the urge to use JSL, then I suggest that you get control of yourself and resist the urge, because it is really awkward. (As well as interesting, from a hacker perspective.)

Today I started working on a way to achieve the same in Maven 2. This is what I've learned so far:

Howto

The site rendering mechanism in Maven 2 is no longer based on JSL, but on a combination of Velocity and Doxia. Velocity is - well I guess you all know Velocity. Doxia is the mechanism used for rendering the reports and transforming documents between different formats. If you want to change the site layout, then you should - at this stage - not be worried about Doxia. Doxia will become relevant if you want to generate reports yourself, or if you want to change the HTML of the reports being generated.

SiteMojo

The component responsible for rendering the site in Maven 2 is the SiteMojo component. This component accepts a number of properties to customize its behaviour. At this stage, there are two customiziation properties you should know about. The first one is the template property. This property allows you to set the name of the Velocity template containing all of the required templates and macros. By default, it will refer to a template file called "maven-site.vm".

The maven-site.vm file is included as a resource in the Maven 2 Site plugin. (Or stated otherwise, distributed as a resource included in the same jar as the SiteMojo class itself.) Overriding the template property on the SiteMojo will still result in the Mojo trying to resolve the template using the classloader mechanism. If you want to change that, then you should also modify the templateDirectory property.

Getting Started

I dediced to start this excercise by copying the maven-site.vm template from the Maven sources to a new directory (/home/wilfred/workspace/maven-template/). After that, I change the pom.xml file at the top of my project to include these lines:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-site-plugin</artifactId>
        <configuration>
          <templateDirectory>file:///home/wilfred/workspace/maven-template/</templateDirectory>
          <template>maven-site.vm</template>
        </configuration>
      </plugin>
    </plugins>
  </build>

After a test run (mvn clean:clean site) it appears that the site is getting rendered correctly, without getting a different layout of course. Note that the templateDirectory property is set to an absolute URL. I haven't been able to address something relative to the ${basedir} - but then again, it is questionable if you would want that at all.

The hard part

As soon as you have your own maven-site.vm template, you can basically start to modify that template and examine the results after running mvn site.

( Oct 25 2005, 01:12:59 PM CEST ) Permalink Comments [2]
20051020 Thursday October 20, 2005

Maven 2 Released

Yes! The official release of my favorite IoC-for-development tool has finally arrived. The Maven guys have been exposed to a lot of criticism during the last few months, since they basically did a complete redesign of Maven 1, but I think they deserve a warm applause for having the guts to push through.

Let's see if I can now officially release some of my own Maven 2 based work that I have been doing during the last few months. I still ran into some problems using CVS and the release plugin, but I've seen some messages on the alias that suggest that it has been solved.

( Oct 20 2005, 02:00:56 PM CEST ) Permalink Comments [0]
20051017 Monday October 17, 2005

Parameterized Dependency Injection

A couple of weeks ago, I blogged about using annotations to specify the kind of Expression instances that need to be injected into objects that have a requirement for such Expression instances.

I basically wanted to be able to do something like this:

...
@Expression("a * (b + c)") private Expression expression;
...

... and rely on some kind of Dependency Injection mechanism to use the @Expression annotation to construct the appropriate Expression instance into the object that requires it.

This weekend, I constructed the code that allowed me to do this using Plexus. This implementation differs from Chris Nockleberg's implementation in number of ways:

  • It uses the BigNumbers foundation. ;^)
  • It does not rely on a specialized container.
  • It injects objects, whereas Chris's implementation adds implementations of abstract operations.

So I did not want my container to have any special knowledge of the annotations that I'm using (unlike EJB 3.0), and I neither wanted to wire my objects together in a special configuration file. I wanted instances of my classes to snap together automatically, and rely entirely on the annotations found at runtime to configure themselves correctly.

I haven't found too much evidence that this can be done by the default mechanisms in existing IoC frameworks, like Pico Container, Nano Container or Spring. So what I needed was a kind of callback mechanism, informing objects of the fact that they had been injected into another object, passing in the annotations associated to the field in which they had been injected.

Since none of the IoC frameworks seemed to offer something like this - most of the lifecycle callbacks are defined on the object in which data is injected - I decided to craft my own DI mechanism... Just kidding. I decided that I would tweak Plexus a little to support the mechanism I needed.

Now the key thing that I added to the Plexus container is an Injectable interface. The Injectable interface allows objects to be notified whenever they are injected. The injected operation defined on Injectable accepts a java.lang.reflect.AnnotatedElement, containing all metadata of the field into which the object is injected. This allows the object to tweak itself to fit the requirements of the receiving field.

In project BigNumbers, that results in the following general structure:

In the figure above, the PlexusExpression is a fairly simple implementation of the ordinary Expression interface. This Expression implementation is however not constructed using an ExpressionBuilder, but it can simply be instantiated. It has one field of its own that is also subject to Dependency Injection by the PlexusContainer, which is the builder field. Because of the way Plexus works, we can configure this field by simply adding one of the ExpressionBuilder jars to the classpath of a project. Plexus will recognize the need of a builder and inject the only implementation found into the PlexusExpression's instance builder field.

The CalculatedObject has just been made up for demonstration purposes:

public class CalculatedObject {

  @BigExpression("a + b")
  private Expression sum;

  public BigDecimal useSum(BigDecimal a, BigDecimal b) {
    return .....;
  }
}

Plexus will notice the Expression requirement of instances of this object (using regular Plexus mechanisms), and notice that there is one implementation available: the PlexusExpression class. It will construct and instance and inject it into the CalculatedObject. Now here comes the real difference with the existing version of Plexus. Normally, this would basically mean the end of the composition phase in Plexus. However, I added a new type of composer to Plexus. This composer (that has been set as the default composer for PlexusExpression) will invoke the Injectable.injected(AnnotatedElement) operation on composed object, if it implements the Injectable interface. Since PlexusExpression does implement this interface, it will have an opportunity to find out which expression it needs to represent, using the field annotations passed in.

Now with all of this, it seems like a great deal of work to get this working, but the opposite is true. As long as I load an instance of CalculatedObject using my slightly reconfigure version of the DefaultPlexusContainer, I get the rest for free. Again, note that the container itself is not aware of something like Expressions. It simply allows the injected object to adapt itself to the requirements of the receiving field, at runtime. Hence, "parameterized dependency injection".

PlexusContainer container = ...;
container.initialize();
container.start();
CalculatedObject object = (CalculatedObject) container.lookup("CalculatedObject");
BigDecimal result = object.sum(BigDecimal.ONE, BigDecimal.ONE); // 2
container.dispose();

( Oct 17 2005, 09:06:52 AM CEST ) Permalink Comments [0]
20051014 Friday October 14, 2005

Maven 2 NetBeans Plugin Installation Howto

This howto provides several options for installing the Maven 2 NetBeans module.

Prerequisites

  • Make sure that you have NetBeans 5.0 Beta installed (or some NetBeans 5.0 development version).
  • Make sure that you have the latest version of Maven 2 installed. (Probably beta-3.)

Installation Option #1

The first way to get it done is by adding a "mirror" of the central Maven 2 repository to your settings.xml file:

<mirror>
  <id>agilejava-mirror</id>
  <name>Agilejava Mirror</name>
  <url>http://agilejava.com/maven/</url>
  <mirrorOf>central</mirrorOf>
</mirror>

If you now go to a directory containing a project for which you need NetBeans support, you simply type m2 netbeans:netbeans. This will at least download the meta files and poms of the NetBeans plugin. You may however discover that it fails to resolve all depedencies. That's because agilejava.com is not really a mirror of the central Maven 2 repository. So you may for example discover that it attempts to download stringtemplate-2.2.jar, which doesn't exist in the agilejava repository.

The only way that I can think of to solve this is to go back and forth between a version of the settings.xml that does contain the mirror definition and a version that does not contain the mirror information. But I would be happy to hear about other solutions.

Installation Option #2

An alternative approach is to create a mirror yourself, using maven-proxy. Maven-proxy allows you to create a mirror yourself, which is nothing but a thin virtualization layer on top of existing Maven repositories. The cool thing about is that you can set your mirror properties in your settings.xml file. If you add your own local maven-proxy instance as a mirror, and configure it to use both the agilejava repository as well as the central repository, then it will correctly download all of the missing files.

The big disadvantage is of course that you would need to install maven-proxy.

Installation Option #3

Download the files manually from agilejava.com. Not sure if this works. I haven't actualy given it a try, but I don't see why you wouldn't be able to make all of the required modifications to your local repository yourself.

( Oct 14 2005, 11:52:32 AM CEST ) Permalink Comments [1]

Maven 2 NetBeans Plugin Distribution Hassle

Yesterday, I said there was only one thing that I didn't like about Maven 2, which had something to do with Eclipse. Today, I think I can add a couple of other things.

I just went through a tremendous amount of effort to make sure that my plugin can be installed on somebody else's laptop. Whew! That wasn't easy at all!

Uploading to the Maven 2 Repository

First of all, I would really like the NetBeans plugin to end up in the maven-components subversion repository. This is where all of the other default plugins reside, like the maven-javadoc-plugin and the maven-eclipse-plugin. I sent out a message yesterday to the mailing list, trying to figure out how to get it uploaded, but I didn't get any response at all. (This may have something to do with the fact that Maven 2 RC1 is about to be released....)

Installing from other repository

So I can't get things uploade in time in the Maven 2 repository at http://www.ibiblio.org/maven2/. The first alternative seemed to be to just upload it to another repository.

Uploading

But which repository. I figured that I would use my own, hosted at http://agilejava.com/maven/. I had used ftp support in Maven 2 before, so I changed the pom.xml to include the repository location, and did a m2 deploy. What the...?!! It appears that wagon-ftp is no longer activated in the Maven 2 distribution, so that didn't work at all.

Since Maven didn't help me anymore and LunarPages doesn't give me scp support, I ended up doing it manually. I didn't have a proper FTP client though, so I first needed to build gFTP. *sigh*

It seemed that the only way to do this properly was to call m2 release:prepare and m2 release:perform first, but it appears that this plugin no longer works with anyhting else than subversion. And I don't have subversion either. I *did* consider building subversion especially for this purpose, but I got control of myself just before I started. Heck, let's just skip making an official release.

Downloading

Remember that the ultimate goal of this entire excercise is to allow other people to install the plugin. The first time I gave it a try, it didn't work. I removed the relevant artifacts from my local repository, and invoked m2 netbeans:netbeans. Maven correctly downloaded the meta data associated to this plugin, but then for some reason concluded that it couldn't find an appropriate version of the plugin.

It began to feel like I wasn't going to end up anywhere at all... I looken into the repository, and noticed that there were now two different meta data files. One 'downloaded' from central (http://www.ibiblio.org/maven2) and another with a trailing keyword indicating that it was downloaded from my own host. I assumed that it was because of these two files that Maven lost track of what it was doing.

So maybe I should fool Maven in thinking that it downloaded the file from the central server. It took me half an hour to install and configure maven-proxy. Maven-proxy sits between Maven and your own local and remote repositories. It makes Maven believe that it is accessing a single repository, whereas in reality it is just accesssing your hard drive.

When I finally got it working correctly, it did download the files, but it still failed to proceed.

.......

I'm skipping over some of the other things that I've tried. Eventually I noticed that my own maven-metadata-central.xml file was missing <release> tag. In the end, it appeared that everything worked just fine when I added this tag. Darn. It took me about the entire morning, installation of a myriad of tools, examining network traffic with Ethereal and downloading the Maven sources to get it done.

Any way, it works - in some sense..... I'll add a quick installation howto in a minute.


( Oct 14 2005, 11:17:44 AM CEST ) Permalink Comments [2]
20051013 Thursday October 13, 2005

Maven 2 NetBeans Plugin

One of the things that I hate most about Maven 2 (and that's really all I hate about it: I like it a lot!) is the fact that it has better support for Eclipse than for using NetBeans. Even the earliest Maven 2 distributions (alpha-0?) provided a way to generate the Eclipse project files, using m2 eclipse:eclipse. It's not the full Mevenide support, but it's definitely useful. It sets the paths to external libraries correctly, sets the source and test directories and a couple of other things, and that's really all it takes to get started.)

Today, I crafted my own NetBeans version of a similar Maven plugin. It's fairly simple: you simply type m2 netbeans:netbeans, and it will generate the missing NetBeans project files for your Maven 2 project. I was a little worried that it would be an aweful amount of work, but it really appeared to be quite simple.

So here's an example. In this case, I'm going to generate NetBeans project files for the Maven 2 NetBeans Plugin itself. Here's the POM:

<?xml version="1.0"?>
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-netbeans-plugin</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>maven-plugin</packaging>
  <name>Maven 2 Netbeans Plugin</name>
  <description>
    The NetBeans equivalent of the eclipse:eclipse m2 plugin.
  </description>
  <dependencies>
    <dependency>
      <groupId>antlr</groupId>
      <artifactId>stringtemplate</artifactId>
      <version>2.2</version>
    </dependency>
    <dependency>
      <groupId>plexus</groupId>
      <artifactId>plexus-utils</artifactId>
      <version>1.0.2</version>
    </dependency>
    <dependency>
      <groupId>plexus</groupId>
      <artifactId>plexus-container-default</artifactId>
      <version>1.0-alpha-4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-project</artifactId>
      <version>2.0-alpha-3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>2.0-alpha-3</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.0</version>
    </dependency>
  </dependencies>
</project>

As you can see, there are alreay a couple of external dependencies listed here, but the number of jar files that need to be included in the NetBeans project is even bigger: almost all of the libraries listed here have dependencies on other libraries as well.

With this pom.xml project file, I'm going to invoke m2 netbeans:netbeans. This is what you get:

[INFO] Searching repository for plugin with prefix: 'netbeans'.
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven 2 Netbeans Plugin
[INFO]    task-segment: [netbeans:netbeans]
[INFO] ----------------------------------------------------------------------------
[INFO] [netbeans:netbeans]
[INFO] Generating build-impl.xml
[INFO] Generating project.properties
[INFO] Generating project.xml
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Thu Oct 13 16:09:19 CEST 2005
[INFO] Final Memory: 2M/4M
[INFO] ----------------------------------------------------------------------------

After running the plugin, you can open the project in NetBeans, and it will look like the screenshot below. Notice that the source directory has been correctly set, and that all of the dependencies have been resolved to files found in the Maven 2 local repository, so you will have instant code completion.

It appears that building this Maven plugin took only one single source file, of approx. 100 lines of code. The plugin hasn't been submitted to the Maven community so running m2 netbeans:netbeans won't get you anywhere yet. (Normally, you would expect Maven to download and install the plugin automatically. I'll try to carve out some time to get it in the Maven repository.)


( Oct 13 2005, 03:57:40 PM CEST ) Permalink Comments [0]

@JFall

Yesterday, we celebrated Java at the JFall conference in Holland, and I had a great time.

Reunion@JFall

First of all, it was like a big Java geek reunion; I ran into several people from my former lifes at other companies. None of them did Java back then, but they are now all working in the Java space.

Jackpot@JFall

I myself presented Jackpot to quite a big crowd. (It's almost like they hadn't read the warnings and disclaimers in the summary of my presentation. ;-) Jackpot is both a framework for source code transformations and a couple of plugins in NetBeans. It comes with an extremely simple and convenient rules language allowing you to almost script transformations, but behind the scenes it relies heavily on more complex things like the different models that javac builds before turning Java source code into bytecode. So it was quite a relief that - after the talk - I still had everybody in the room.

In fact, they even noticed an erroneous Jackpot rule in one of my slides. ~:^[ And they came up with some interesting suggestions, like using Jackpot to turn untyped collections into typed collections. :^D (Java 1.5)

NetBeans@JFall

After my session, I got to talk to Geertjan Wielenga, part of the NetBeans team and the world's most noticable NetBeans blogger. He showed me how NetBeans 5 allows you to create a new NetBeans module in a blink of an eye, and blew me away completely. I'm telling you, it just can't get any easier than this! This way, even my 5-year old is able to create NetBeans modules. (Is the NetBeans team promoting child labour or something?)


( Oct 13 2005, 10:50:18 AM CEST ) Permalink Comments [0]
20051011 Tuesday October 11, 2005

BFN9000

If you haven't read Chris Nockleberg's comment on my latest Big Freaking Numbers entry yet, then make sure to check it out; he implemented exactly what I had in mind. Awesome!

( Oct 11 2005, 09:40:13 PM CEST ) Permalink Comments [0]
20051006 Thursday October 06, 2005

CGLIB Comes to Rescue

In my previous blog entry, I talked about the problems that we ran into when trying to use a proper template mechanism in combination with a given object model. The problem had to do with the fact that this object model does not expose all of its interesting properties as bean properties. In an attempt to solve it, I figured that it should be possible to provide StringTemplate a virtual copy of the original network of objects, and that CGLIB would help to get it done.

Here's what it would look like. I don't have the time to explain everything in detail, so expect more about this at a later time.

( Oct 06 2005, 03:23:03 PM CEST ) Permalink Comments [0]

Navigating a Dynamically Enhanced Copy of an Object Tree

StringTemplate provides a very nice source code generation mechanism, but it is a little restrictive in obtaining data from the data passed to the template. We ran into this when we wanted to use StringTemplate to generate source code from a Modello model:

  • The ModelloField carries some metadata, but you won't be able to access this data without invoking an operation on ModelField that does meet the bean getter naming convention. The operation to invoke is ModelField.getMetadata(Class clazz). Since StringTemplate is restricted to access only data exposed through bean-alike accessors, you will never be able to call this operation directly from StringTemplate.

  • We needed to generate Java Bean accessors from a ModelField. The ModelField has a property name that we could access, so it seemed to be not that hard. But then we realized that we had to change the ModelField's name to start with a capital in order to meet the cammel case getter and setter patterns: so in case of a ModelloField with name "foo", we needed to generate "Foo" when generating the setter ("setFoo(String foo)") and getter ("String getFoo()").

    As in the previous example, there is no easy way out: there are no bean-alike operations on java.lang.String that allow you to return a version of the String with the first character turned into a capitcal. (So there's no operation like String getSameStringStartingWithUpperCase() defined on java.lang.String.)

Terence Parr has suggested to use connector or "glue" objects in these cases. However, if you want to navigate through a network of objects in your template, then it can be quite challenging to insert these glue objects. And that is exactly our problem: we don't want to replace the entire Modello model by another copy, simply because we need an extra couple of accessors. In the Modello case, we were able to replace the ModelField by a manually constructed Proxy called EnhancedModelField. However, this was a painfull excercise, and now we are starting to see the need for enhanced ModelClass and Model classes as well.

With all of this in mind, we are starting to think about using CGLIB to construct an enhanced replica of the Modello model on the fly. An alternative would be to change StringTemplate to provide support for dynamically inserting "glue" objects. The result would be similar to StringTemplate's support for AtttributeRenderers: you would simply register a Connector class for the types that need to be enhanced, and StringTemplate would wrap the original type with the Connector instance whenever it encounters an instance of the original type.

Let's wait and see how Terence feels about that.

( Oct 06 2005, 07:18:01 AM CEST ) Permalink Comments [0]
20051002 Sunday October 02, 2005

Big Freaking Numbers IV

A couple of weeks ago, I blogged about a simple way to evaluate expressions using project BigNumbers. With all of the boilerplate code still required to get anything at all, I've been wondering how to get rid of it using dependency injection or annotation mechanisms. I haven't really coded anything at all yet, but I think it would be cool to have eventually something like this:

...
@Expression("a * (b + c)") private Expression expression;
...

... and then depend on DI mechanisms to inject an Expression implementation.

( Oct 02 2005, 10:10:08 PM CEST ) Permalink Comments [3]