Maven: Unable to find resources in test cases?

Just right now, I was once again fighting the beast called Maven. This time, my JUnit tests failed with Maven although they used to work within in Eclipse. The test cases failed due to missing resources. I searched for these resources using the ClassLoader.getResource() mechanism which always worked just fine so far.

After some swearing and investigation I finally found the problem: In my code, I used ClassLoader.getSystemResource(...) to find a resource, which internally calls ClassLoader.getSystemClassloader(). However, with Maven’s Surefire plugin, the system classloader does neither contain target/classes nor target/test-classes in its classpath. Therefore, you have to make sure, that the classloader that loaded the test cases (and the tested classes) is used to get the resources.

Therefore, instead of

ClassLoader.getSystemResource(...)

always use

this.getClass().getClassLoader().getResource(...)

Problem solved!


Maven – Curse or Blessing?

Today I spent several hours fighting a beast called Maven. I started using Maven some days ago for a new project. But each and every day I was asking myself the question: “Maven – curse or blessing?”. If you google around a litte bit, you can find lots of developers swearing in their blogs – and so was I today.

Everything was working nicely until I carelessly added several dependencies this morning. Suddenly, my Wicket-based webapp stopped working with some strange exception. A class in Jetty called a method that was not found in the servlet API (javax.servlet). Well, rather strange, I thought. After a little online-research I found that this method was introduced in version 2.5 of the servlet API. I doublechecked with the Jetty docs and yes, Jetty 6.1 implements exactly this version of the servlet API. Well … so what’s wrong?

But then I noticed that Maven added two different versions of the servlet API to my dependencies: 2.3 and 2.5. But isn’t Maven meant for resolving such conflicts? In deed it is and it actually wasn’t Maven’s fault. While Jetty comes with its own version of javax.servlet (called org.mortbay.jetty:servlet-api-2.5 in Maven), Maven added javax.servlet:servlet-api (version 2.3) as a transient dependency.

So how to get rid of unwanted dependencies? In Maven it is possible to exclude transient dependencies. The problem is that you have to do that for every package that depends on this unwanted package. You have two choices to find out which package depends on it: you either look at the POM of every dependency and the POMs of their dependencies … or you look at the dependency tree that can be generated with Maven’s dependency plugin (mvn dependency:tree). Well, the tree-task didn’t work for me, for whatever reason. I remembered that the dependency tree was also part of the project website that can be generated with Maven’s site plugin. I did generate the project’s website (mvn site) and there was also a dependency tree … but javax.servlet:servlet-api wan’t in that tree … but in the list of transient dependencies. If I remember correctly that was were I started swearing. So it was time to manually inspect all the POMs. (For the sake of completeness: I think that the servlet API wasn’t in the dependency tree as it only contains three levels of dependencies.)

I started analysing the POMs one-by-one and found out several interesting things:

  • Some POMs added junit as dependency without specifying the test-scope (it would therefore be added to the generated WAR file)
  • Optional dependencies and alternatives are not defined consistently: sometimes all optional dependencies are normal dependencies, sometimes none of the alternatives is a dependency, … altogether it’s quite messy

I finally found the dependency that added version 2.3 of the servlet-api to my dependencies: commons-logging. Yes, exactly that commons-logging that is basically meant to write some lines into a file. Why does it depend on the servlet API? Because it has its own logger that is supported by commons-logging and the commons-logging POM has dependencies on all supported logging implementations:

So you have to explicitly exclude the dependencies you don’t need … or you will deploy your desktop application with the servlet API. And the best thing of all: you have to do that for each and every dependency that introduces commons-logging to your project dependencies.

I then decided not only to exclude all unnecessary logging-frameworks but commons-logging all together in favour of slf4j. Unfortunately, it’s not possible to globally exclude a package all together – as Maven developers want to “protect” you from doing that – excluding commons-logging can get quite complicated. Erik van Oosten came up with a nice workaround for this topic. He announced a faked Maven repository that offers an empty jar file with version 99.0-does-not-exist for all artefacts you ask it for. So if you explicitly depend on this version, no lower versions will be added to your dependencies. And if you mark this dependency as provided, it also won’t be included in your WAR files. Yes, it’s a hack, but it’s a nice one ;)

Besides a small problem with empty jar files that Erik is going to fix (see my comment in Erik’s blog) the whole thing works like a charm – no commons-logging, no version conflicts with the servlet API, everything is fine.

I think I still can’t answer the question whether Maven is a curse or a blessing. The only thing I can say is that Maven has its problems, but also great power. I’d say it’s very important that you really go into the topic before you use it. Maven is big, *really* big. It’s not like Ant that you can start using after reading a short tutorial. If you don’t know how Maven works it will certainly kick your ass. But if you know how to handle that beast, it really kicks ass ;)

However, I am still not happy with the official Maven repositories. They are completely messy and Maven is not really helpful in coping with this mess. I would really love to see something similar to Debian package management: with provides, depends, suggests, recommends, meta-packages, nice updates … and a repository that is under tight control. Maybe even the new Ant subproject Ivy is a step into the right direction (I would love to see it in action together with Maven). But for the moment the only thing you can do is to have a close look on each and every POM in your tree of dependencies. Yes, it is extensive work, but it’s the only way to reduce your dependencies to a minimum … And dear Maven developers: please don’t try to prevent us from doing evil things, as we might do them anyway (like using version 99.0-does-not exist). Just give as the freedom to do what we want to do.


Some wicket impressions

I already mentioned Apache Wicket in my first post and immediately received advice to not gloss “over a great framework too quickly”. This advice came from a guy named jonathan … coincidentally one of Wicket’s most ambitioned developers is Jonathan Locke, who’s always present in discussions about Wicket … so there may be a connection to that guy who left a comment to my first post :-) .

So I gave it a try. As the Wicket website suggests to use version 1.3.0beta, the first I did was to download it as maven dependency.


<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>${wicket.version}</version>
</dependency>

<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-extensions</artifactId>
<version>${wicket.version}</version>
</dependency>

Then I took a look around to find some code snippets or examples that could give me a smooth start. The guestbook example on the website was the first a had a look at (well after the hello world, which doesn’t count :-) ). The guestbook was easy to understand and ran without problems …
Wicket’s AJAX support was the next thing I had a look at. I found some nice examples in the Wicket Library and on wicketstuff.org (in fact the same on both websites). And yes, it was the guestbook with added ajax behaviour which I tried first. I adapted it a bit to my needs and tried to run it. It ended up by throwing a MarkupNotFoundException which suggested to

Enable debug messages for org.apache.wicket.util.resource to get a list of all filenames tried

as Guestbook.html could not be found. I enabled debug messages by adding the following line to my log4j.properties file.

log4j.category.org.apache.wicket.util.resource=debug

The debug message I got was

[DEBUG] ResourceStreamLocator Attempting to locate resource 'org/example/wicket/Guestbook.html' on path [folders = [], webapppaths: []]

I thought “uh, there aren’t any webapppaths or folders in wicket’s path, gotta add some”. I then entered the path in the web.xml file as property of the Wicket filter. Well, the path was then inside the brackets, but the exception still got thrown.
Eventually I saw the (my) mistake: there was a <wicket:extend> tag in the markup html, which was completely new to me. Having read the wiki article about markup inheritance and having removed the tag, the Guestbook ran without problems. Yepp it was my mistake to copy-paste the thing and to overlook the tag, but couldn’t the error message be a bit better/concise?

Alastair Maw’s BeanEditPanel reminded me a lot of Tapestry’s BeanEditForm, but of course doesn’t have all the BeanEditForm’s functionality (yet). But it was a great starting point for me to get a bit more into wicket … I already extended the BeanEditPanel a bit … yes, to be honest, the more I work with Wicket, the more I like it. The use of plain html and wicket IDs is a great concept and I also like the ease of adding AJAX behaviour. Just have a look at the ajax examples.

A nice summary of wicket’s features can be found in Peter Thomas’s Blog. I also recommend to read Karthik Gurumurthy’s introduction.

The only complaints I have so far are that I could not find the source code, which would be quite comfortable to have attached to the jar, as I sometimes like to see what’s going on behind the curtain… and no I don’t want to check it out from the SVN :-) .
There’s also no link to the 1.3.0beta javadocs on the official website. I found the link in a newsgroup post.

What I’m going to find out next is how the Validators work in Wicket. In a example I found, a Validator was added to a text field for instance like that

TextField name = new TextField("name");
number.add(StringValidator.minimumLength(5));

But contrary to the javadocs, a method FormComponent.add(IValidator) is not available … which I found a bit strange …

That’s all for now, and comments, especially to the validator stuff, are always welcome ;-)


Creating custom components with Tapestry 5

As far as I’m concerned, I consider creating custom, reusable components as the supreme discipline of every web-framework. I remember fiddling about a custom tabbed panel in JSF some years ago … those were the days when it wasn’t easy to find JSF third-party components. I also remember that it took me ages to add some sort of AJAX behaviour, and I can’t really remember if I finally succeeded :-) But times have changed, creating custom components is part of every almost every framework’s ref-docs and it is … or should be … easy to create them. Ideally just with combining already existing components to new ones.

As already mentioned in my previous post, I’m playing around with Tapestry 5 these days. So I decided to create my own component, a guestbook component. The guestbook should be as generic as possible, meaning that all kinds of Java beans should be valid entries. I.e. you should not be dependent on some fixed values such as name, e-mail and the message … well that really called for a BeanEditForm to enter the values … and I thought about using some kind of Grid to display the guestbook entries.

As a complete newbie in creating tapestry components, the first way to go was the Tapestry wiki’s howto page for T5. There, Eric Vullings’s short introduction about creating custom components merely gave me a quick overview over the rendering phases to override/implement when creating a component.
Then I took a cursory glance at the BeanEditForm’s and Grid’s source code to see how the components work and how they could be extended/used for my custom guestbook component. I quickly realised that it takes a bit more than a cursory glance to get the hang of the Grid (including the GridRows, GridColumns and GridPager components) but it needs less effort to figure out how the BeanEditForm works.

I decided to take the BeanEditForm straight away as part of my component and to adapt some of the Grid’s functionality to display the entries. I soon found myself copying most of the Grid’s code …. that was the right time to stop and to think about my approach once again. I was already down in adding my own coercer to the AppModule which was a lot of fun but nevertheless copying code can’t be the solution :-) .
So I (ab)used the Grid for my custom needs. To keep it short (sorry for those of you who didn’t get in touch with the Grid so far :-) ), I let my Guestbook implement the GridModelProvider interface, subclassed GridRows in order to be able to use the a different template-html without losing the GridRows’s functionality and did the same with the GridPager component.
There it was, the Guestbook – a BeanEditForm above with GridRows and a GridPager below. All it needed now was to override the onSubmit method (or to use the @OnEvent(value = “submit”) annotation) to do with the new entry whatever I wanted.

But after all, it just didn’t feel right to abuse the Grid and to call that my “custom component”. I think I’ll never use it in a real-life application, but I got a good insight into how components work in Tapestry5 by playing with those two. Here my two pennies worth on the whole stuff:

The ‘mighty’ components in Tapestry5 seem to be hard to extend – maybe it is better to use them as they are, without trying to combine them to form a new component (which might be what the developers wanted). I believe that it wouldn’t be too difficult to create mighty components on your own, if you already created some small components. There were two little things I noticed during dealing with the GridPager component:

  • The GridPager component shouldn’t be limited to the Grid. In its current state it requires a GridDataSource object, which actually is the only link to the Grid. Basically it’s just a matter of a different naming. Thus creating a super-interface of GridDataSource (e.g. DataSource with the method getNrOfItems():int) would make the GridPager reusable for other components without having the Grid-stuff in it.
  • The CSS-class shouldn’t be hard-coded. Overriding the css would be a possibility, but it would look much neater to pass it as a parameter.

Well, that’s all for today. I’d love to hear about your experience with creating your custom components. So if you have something to say, or questions, just leave a comment below!

Unfortunately I did not find the time to look a bit more into Maven. Now even Tapestry creator Howard Lewis Ship swears like a trooper in his recent blog entry :-) . I’ll definitely have to take a more thorough look into Maven …


Tapestry/Spring Integration

In the last weeks I started to have a look at different web frameworks and came across Tapestry5. Having watched the screencasts on the website, I began to like it straight away. Although still in development (the release is planned in fall 2007), it offers some nice features. The most impressive one is that you do not have to restart the servlet-container to apply changes in java files. But for me personally, the features I appreciate the most are that you don’t have to bother with jsp-specific stuff (such as <% useBean="..." %> – Ugh!) and it lets you get rid of the servlet mapping stuff in the web.xml. That’s nice isn’t it? I also read some posts claiming that Apache Wicket already provides such features. I started reading the Wicket docs, but stopped when I saw that there’s a need to inherit from a Wicket base-class and to define servlet-mappings in the web.xml – as stated above, I don’t like too many manual servlet-mappings and I also prefer dealing with POJOs.

After playing around with Tapestry by implementing the screencasts and the tutorial, I tried to inject Spring2 managed-beans into a Tapestry5 app. I found a load of examples/tutorials online, but they either dealt with tapestry4 and/or spring1.2.x. There also is a tutorial on the Tapestry site from its creator Howard Lewis Ship. Unfortunately, he missed pointing out that it is vital to add another dependency, the tapestry-spring library. Worth mentioning is, that the tapestry-spring dependency differs from the tapestry-spring.jar available on the project page which I used at first. It took me quite a while to find out what’s wrong until I found a hint in the tapestry-mailing-list. A user there suggested to add the tapestry-spring dependency to your maven2 pom.xml. After including the library, a simple @Inject was enough to inject a spring-bean into the tapestry-class. The dependency should look as follows:

<dependency> <groupid>org.apache.tapestry</groupid> <artifactid>tapestry-spring</artifactid> <version>${tapestry-release-version}</version></dependency>

The hacks I did with Tapestry5 made me to get in touch with Maven2 for the first time. Together with the eclipse-plugin, it was very easy to add dependencies to the project and to build and pack the application. That’s of course only the tip of the iceberg, and I’ll definitely have to get a bit more into maven – as it really looks like it offers some nice features. And also I have to prove if Jelmer Kupurus’s statement is right or not :-)

Enough for now, I’d love to receive some comments with your experience with Tapestry5 and Spring integration!