Using Maven2 projects at googlecode.com

googlecode.com offers a nice hosting platform for your open source projects. You get SCM (either subversion or mercurial), a wiki, a bug tracker and download facilities.

Here are a few tips to facilitate Maven2 project integration with it (subversion is used as I am not familiar with mercurial yet).

Subversion access configuration

Add those informations in your pom.xml

<scm
<connectionscm:svn:http://my-project.googlecode.com/svn</connection
<developerConnectionscm:svn:https://my-project.googlecode.com/svn</developerConnection
<urlhttps://my-project.googlecode.com/svn</url
</scm

When accessing the subversion repository (for instance while using maven release:prepare and maven release:perform) you must provide googlecode username and password to maven, using command-line parameters

-Dusername=googlecode.username -Dpassword=googlecode.password

or by modifying your settings.xml file

<server
<!-- Will be used for scm connection --
<idgooglecode.com</id
<usernamegooglecode.username</username
<passwordgooglecode.password</password
</server

Your googlecode password can be found under source tab of your googlecode.com project website, click on ‘When prompted, enter your generated googlecode.com password.’.

Issue management configuration

Add those informations in your pom.xml

<issueManagement
<systemGoogle Code</system
<urlhttp://code.google.com/p/my-project/issues/list</url
</issueManagement

Repository on subversion configuration

You can rely on googlecode subversion to provide access to your maven artifacts.

Add those informations in your pom.xml

<distributionManagement
<repository
<idmy-project-release</id
<urldav:https://my-project.googlecode.com/svn/maven2/releases</url
</repository
</distributionManagement

An alternative would be to rely on the subversion wagon implementation as described here.

You will also need to modify your settings.xml file to provide googlecode.com credentials.

<server
<idmy-project-release</id
<usernamegooglecode.username</username
<passwordgooglecode.password</password
</server

Web pages hosting

If you want to send html/css files to your svn repository and still be able to normally browse them you will have to fix the mime type which is defaulted to ‘text/text’. If you are using subversion you can manually set the mime type with those commands:

svn propset svn:mime-type 'text/html' *.html
svn propset svn:mime-type 'text/css' *.css

Maven redmine plugin

FastConnect uses redmine for its opensource platform to track features/bugs off all its projects. Unfortunately there is no integration with maven as you can find with Jira. Especially it lacks the capacity to retrieve all features/bugs part of a specific Roadmap release.

Toward full release automation

maven-redmine-plugin provides tight integration with maven-changes-plugin (at least the tightest possible) by creating changes.xml file from a redmine roadmap. This allows to create nice changes report in your maven site and to send release announcement email.
Then you can publish a news to your redmine project advertising the new release.

All of this rely on information provided in your pom.xml and can be automatically executed as part of a release by configuring maven-release-plugin.

More details about this configuration here.

Spring Hibernate and GWT Integration built with Maven

I worked with a colleague, Xavier, to build a kind of “best of breed” Web 2.0 technologies project template that we could reuse from project to project.

Our aim for this project was to :

  • build a simple Web 2.0 project based on the technologies or libraries we like to use in Java EE today’s world (GWT, Spring, JPA/Hibernate, Acegi, Maven)
  • and to create a Maven archetype (as we didn’t found anyone which already provides integration of  these technologies together).

Let’s consider the following architecture : we have an existing domain model and a traditionnal multilayered application (business layer, data access layer, database), and we want to be able to use GWT as the presentation layer.

Basically, points we wanted to take into consideration were :

  • how can GWT interact with Spring ?
  • managing Hibernate lazy collections.
  • how can Acegi be used to improve security of such a GWT based application ?

A Maven based project

We’ve started using the archetype gwt-archetype.

This archetype provides a Maven based project with a simple GWT client.

With the gwt plugin maven-googlewebtoolkit2-plugin, we are able to launch the GWT Debug Console and also the embedded Jetty container with the Jetty plugin for Maven.

GWT / Spring communication

Several scenarii are available to integrate GWT and Spring.

We have tested 2 of them :

Strong integration , following Chris Lee’s post GWT-RPC with Spring 2.x.

GWT services are beans, configured in the Spring context. You annotate them with a custom annotation @GwtRpcEndPoint.

Then you write your own class extending Spring’s AbstractDetectingUrlHandlerMapping class. Its role is to detect the annotation and to generate urls that will be handled by Spring and mapped to corresponding ‘controller’.

Finally, you write an another class that extends RemoteServiceServlet (provided by GWT) which is responsible to handle RPC calls.

This first approach looks good for IoC purists : GWT services are not servlets, and you can even think about using your business layer as GWT endpoints.

But is this really a good idea ? It seems like a violation of SoC paradigm, isn’t it … ?

Whatever, when considering the use of Hibernate, that also needs to rewrite parts of RemoteServiceServlet, you come into troubles …

So we have finally choosen a kind of light integration : GWT services simply get business service implementations from context.

In their init() method, GWT endpoints – that extend RemoteService, so Servlet by inheritance – get their dependencies from the context.

BeanFactory factory = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
taskManager = (TaskManager) factory.getBean("taskManager");

Don’t be offended (as we initially were !) by this approach : just consider GWT layer as a presentation layer which comes on top of an existing Spring multilayered architecture, as we mentioned in the intro.

GWT / Hibernate communication

We wanted to use Hibernate as an implementation of JPA specification for differents reasons : convention over configuration, choice for implementation, standard use.

At the time we had chosen to use the freshest GWT build which was a pre-release of version 1.5 since it supports Java 1.5 features : annotations, generics.

However, we can’t use our Hibernate objects directly.
As we can read in the post Why GWT 1.5 won’t solve your Hibernate issues : “Hibernate POJO are not real POJO. The persistence library adds a lot of needed information, such as session factory, by creating a dynamic proxy (with CGLIB or Javassist) around your instance. When you manipulate an Hibernate POJO, you do not do it with an instance of your class, but with a instrumented, derived one!”

As a consequence, we have to duplicate our domain model. One domain for backend processes (typically POJOs with JPA annotations), and one other domain for GWT serialization processes (DTOs).

As managing this duplication can sound bad, we have chosen hibernate4gwt, a library that can help us managing this.

As you can read in its documentation, hibernate4gwt offers different ways to manage domain model duplication : stateless, dynamic proxy, Java5 support and stateful.

Since dynamic proxy seems to be the less intrusive for our POJOs, it gained our preference.

(Moreover, with 1.5 GWT pre-release, we can use our 1.5 annotated POJOs.)

Initially we wanted to use stateless mode, but having unresolved issues with StatelessPojoStore down the road we decided to use HttpSessionPojoStore.
May look like a hack but it worked and allowed to avoid building in-house code.
More importantly we thought duplicating the domain objects could be an error prone task.

Acegi

Then we started to focus on security.

Considering using Acegi in a GWT project gives us 2 solutions.
We have tried to use a HTML form to authenticate. This is simple but is incompatible with the use of GWT console to debug the application. Effectively, GWT Console needs a GWT module to run, it doesn’t want to know anything about html pages.

So to be able to debug our application in the GWT console, we have preferred the second approach which in fact is to use a second GWT Login component : a single EntryPoint which declares a FormPanel, which posts to j_acegi_security_check.

We have included a simple Acegi configuration file : if you are not authenticated, it enforces you to login by redirecting you to the login module.
Authentication is made upon the database with a DaoAuthenticationProvider, which takes as a parameter a custom implementation of UserDetailsService. This one uses the service layer to look for the users in the database.

More informations :

How to build the project : https://opensource.fastconnect.org/redmine/wiki/spring-gwt-archetype

Sources : http://opensource.fastconnect.org/svn/toolbox/maven2/archetypes/hibernate-spring-gwt-archetype/trunk/

Enhanced GigaSpaces Maven integration

Latest GigaSpaces release (6.5) comes with an integrated Maven facility. This support is provided through 2 functionnalities:

  • a script and associated set of poms to install GS jars in your local repository
  • a plugin providing hability to create a pu based on a templte, start a local pu container and deploy pu to a running GSM

This is a great news for the GS users’ community and confirm that Maven becomes an entreprise player. Unfortunately this plugin does not really fit into Maven architecture and way of thinking. Prior to Maven support in GS product we developed internally a number of plugins whose functionalities are similar but (in my purist opinion) more Maven friendly.

Leverage Packaging type

Maven packaging allows to choose how your project will be packaged. maven-pu-plugin allows to use a pu packaging which will -what a surprise!- generate a pu instead of a regular jar.

Cargo as a de facto container abstraction standard

Cargo framework supports a good variety of container and facilitates their manipulation through a common API from Java, ant and maven. cargo-container-openspaces provides OpenSpaces container to cargo (currenlty only standalone container).

How does it help?

The difference between those plugins and GS relatives is not only about clean integration. This tight integration with maven simplifies deployment as pu is a first class citizen.
Furthermore Cargo plugin fully supports pu packaging type which makes integration tests as part of the lifecycle of your project feasible.

See following project for a sample on how to use both plugins.