Archive for February, 2007

Next generation web frameworks

Wednesday, February 28th, 2007

As some might have read on several websites (like here, here and here): Struts 2.0.6 has officially been released.

I was already testing the new up and coming framework and was very pleased with it’s easy of use. While I was doing so I read about the new Tapestry. Just like Struts this framework is a very different from it’s predecessor.

I started thinking on all the frameworks I have been watching evolve and grow and saw one common technology use: they are all based on servlet filters. Tapestry, Struts and also SiteMesh as based on filter technology and use a decorator pattern to generate the view. Filters are (as you all know) not really a new thing but it looks like it has recently been (re)discovered.

Maven and transitive dependencies

Wednesday, February 7th, 2007

I am currently working on a very large project that currently consists of 25 modules. We where having a lot of exceptions being thrown around so I decided to search for a solution.
I discovered that our application that is one of the modules had a very long list of jar files in the lib directory that should not be there. A lot of jar files where duplicates. We had three different versions of commons-collections and two different version of command-lang. This could have been the cause of all our problems. I solved this by adding excludes to the dependencies that provided older versions of the jar files. To find the culprit dependency took a lot of searching in pom files (local in the project or remote on our maven proxy). We used commons-cli to parse the incoming arguments this provided a very old version of commons-collections and commons-lang.
The original dependency is as follows:

<dependency>
	<groupId>commons-cli</groupId>
	<artifactId>commons-cli</artifactId>
	<version>1.0</version>
	<scope>compile</scope>
</dependency>

And I changed it to:

<dependency>
	<groupId>commons-cli</groupId>
	<artifactId>commons-cli</artifactId>
	<version>1.0</version>
	<scope>compile</scope>
	<exclusions>
		<exclusion>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
		</exclusion>
		<exclusion>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>

This solved our duplicated jar files problem.

On to the next problem. In our web module called frontend we had a jar file called: asm-2.2.jar. We also are using Hibernate in our project but it depended on asm-1.5.3.jar and the versions are NOT compatible. It gave us ClassNotFoundExceptions.

After some searching I discovered that the newer version of the jar came from a dependency on groovy. Groovy was included as runtime dependency for our struts (1.3.5) scripting part of the application. I tried to use the same solution as I did with the previous problem but that did not work.

The dependencies within out project might be a bit complex; below is the persistence part of our application:

project
   |
   +--persistence
          |
          +--persistence-util
                  |
                  +--Hibernate
                        |
                        +--asm(1.5.3)
                        |
                        +--cglib
                        |    |
                        |    +--asm(1.5.3)
                        |
                        +--(others)

In our frontend project we have a dependency on the persistence module and on groovy. Groovy in his turn is dependent on asm-2.2.jar. When we exclude the asm library from the transitive dependency in the groovy dependency maven removes them all!

The only solution we could find was to remove the groovy library as scripting facility all together. It seemed that the application run fine without it anyway :D

Serving RMI objects

Tuesday, February 6th, 2007

I was trying to get RMI working for a project of ours but I get getting strange exceptions:

Exception in thread "main" java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.lang.ClassNotFoundException: org.limmen.rmi.api.Hello
        at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:385)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
        at sun.rmi.transport.Transport$1.run(Transport.java:153)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707)
        at java.lang.Thread.run(Thread.java:595)
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:343)
        at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
        at java.rmi.Naming.bind(Naming.java:111)
        ...

To locate the bug I probably made I created a HelloService (the RMI version of HelloWorld).

The server creates a registry and binds the HelloService to ‘rmi://my-pc/HelloService’. And the client that runs on a different computer also looks up the service using the same URL. This works…(finally)

I seems that what I did wrong was: I bound the service on the server on the URL ‘rmi://localhost/HelloService’. This seems very obviously but: the client first lists the services it can find and than tries to invoke the service. What did it list? ‘rmi://my-pc/HelloService’ so everything looks OK. Until you invoke it!

Is this a bug? Or am I just interpreting everything wrong here?