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]
20050929 Thursday September 29, 2005

The Seven Stages of SOA Asceticism

If there is one severe risk in the SOA space, then it is probably the chance that people expect SOA to be a free ride. They assume that your architecture will transmogrify into a Service Oriented Architecture, as long as they have the right middelware and tools.

That, of course, sounds too good to be true. And it isn't. SOA doesn't come for free. SOA does not automatically fit into the existing architectures, and getting it right requires dedication and a contemplating lifestyle in which you refrain from some of the worldly pleasures introduced to the Software Development community in the past.

(Uh, well, I'm not sure there are exactly 7 stages of course - there are probably more - but 7 just sounded right.)

1. Refrain From I in ACID

If you have been working in a distributed object computing world, then you probably already know the meaning of the ACID acronym; it means Atomic, Consistent, Isolated, Durable. Those are the properties of the transacation model that most of us have gotten used to in the past. In database terms, it effectively means you can't screw up your database consistency if you have multiple clients trying to access the database at the same time.

The cool thing about these kind of transactions is that you basically don't have to do a lot to get this working. In fact, it is the de facto standard in the RDBMS world. And it's the standard in J2EE environments. So even if you didn't know the acronym, then - my friend - you have have been doing it without being aware of it.

So my first message to all of you is that you should get used to refrain from it. You wonder why? Well, the problem is "I". (What do you know; I'm starting to sound more like a guru with every line.) I don't mean you, I mean "I", not me.

In a SOA world, a business process might take some time to complete. And "some time" can be anything between a couple of seconds between a couple of weeks or more. Even if you would rely on some kind of optimistic locking mechanism, then you would still need the explicit consent of all services participating in the transaction. And during this time, all of your data sources would need to be locked in order to guarantee "Isolation" semantics.

The Isolation property of ACID transactions guarantees that the transation does not affect or is affected by other transactions. This basically implies locking the resources involved for a short period, but you can't do that if the short period expands to a couple of minutes or more. It would effectively lock up your data source forever.

Another problem is the transaction manager. If you decide to open up your services to the outer world, then there must be something coordinating the transactions between your services and your client's services. In the end, you want a consistent state in all of your databases, right? The question is: which transaction manager. Your customer probably doesn't trust yours and you don't trust your customer's. There is no third party out there on the Internet that you could trust. (Not entirely true in all cases, but let's keep things simple.)

So how do we compensate for missing ACID semantics? It may sound silly, but the answer is: with compensation. It means designing your services in such a way that you can always "roll back" manually. The archetypical example is compensation in a flight booking business process. If I book a flight, then the seat will be reserved for me. But if I don't confirm the reservation in time, then the flight booking system will simply "undo" the reservation. It didn't have a transaction that spanned the entire time that I needed to figure out if I wanted to fly or not. It simply defined a "compensating" message allowing them to get rid of my reservation.

WS-BPEL recognizes the need for compensation scenarios and has it built into the language.


( Sep 29 2005, 01:40:13 PM CEST ) Permalink Comments [1]
20050927 Tuesday September 27, 2005

Big Freaking Numbers III

Remember that I talked about the different flavors of ExpressionBuilders in project BigNumbers a while ago? At this stage, there are two of them. One implementation turns the String expression into an Expression implementation that is interpreted for every evaluation. The other implementation took a different (and pretty fancy) approach by compiling the String expression into a full-fledged Java class on the fly.

Today, I did a benchmark to see which one would be more performant. The results are slightly dissapointing. I was kind of hoping that the JIT-compiling version of the ExpressionBuilder would outperform the other one, but it doesn't. *sigh* I expected the interpreter to outperform the other ExpressionBuilder in case of ad-hoc expressions, so I wasn't too surprised when that turned out to be true. However, the JIT-compiling version of the ExpressionBuilder only starts to outperform the interpreter version after 3000-4000 evaluations. And then only by microseconds.


( Sep 27 2005, 03:15:42 PM CEST ) Permalink Comments [2]

BigNumbers -> Maven Beta 2

I just moved project BigNumbers to Maven 2 Beta 1. There are a couple of things that you can expect to occur during the next few weeks:

  • A couple of tests to verify the performance of the different Expression implementations.
  • A refactored project structure that needs to be a little bit more friendly for CVS.
  • A better interpreter. (One that the stuff used by the JIT compiling implementation.)
  • A better parser. (One that doesn't choke on "4 -a".)
  • Power function support.
  • A new release.
( Sep 27 2005, 12:51:21 AM CEST ) Permalink Comments [0]
20050926 Monday September 26, 2005

Maven 2 Gone Beta

It's hard to admit, but Gero Vermaas had to bring to my attention that Maven 2 has gone beta. During the last few months, I've probably been hitting the Maven 2 site a couple of hundred times a day, just to find out about it's latest status. And then, when I least expected it, it arrives...

Let's find out if the wagon-ftp FTP support has been fixed. (And the dreaded bug that prevented me from uploading a project site from Maven 2 using SCP.)

( Sep 26 2005, 08:38:43 PM CEST ) Permalink Comments [0]