Saturday, October 3, 2009

Hibernate, JPA, JAX-WS, Spring AOP, JSF, Facelets, Transactions with Maven and Continuous Integration.

Starting what will hopefully become a series of articles showing how to use the widespread technologies in a web application started from scratch and intended to be deployed on a simple servlet container (Tomcat, Jetty,...) lacking support for advanced J2EE.

In other words, this is sharing simple home-made recipes and hoping to make them better by sharing.

The problem: create a slim and maintainable Java application including a lightweight framework that facilitates CRUD operations. This is a template that would be the starting point of many different projects, and eventually would lead to  creation of a Maven archetype.

What is known: performance is not critical; we should use free software (database and application servers), but not exclude a transition to other technologies in the future. The resulting project should lend itself easily to agile development and continuous integration (this is where things like DBUnit come into the picture).

The set of Java classes thus created can form the core of a lightweight framework that could be used to build different applications using modern Java technologies.

The content was a result of a recent design and development effort, and producing it involved a lot of googling, and very little original effort. Enjoy and comment!
Next articles (work in progress):


Some notes on the choice of technologies
... for those who need that.
  • JPA and Hibernate: first of all, JPA seemed to be the best for a project that starts from scratch as a Java application, because it's a Java-centric technology. It would allow to do domain modeling in terms of Java objects and make the database schema follow that model and the changes in it automatically; performance considerations were written off as "premature optimization", because the application is supposed to be small-scale -- in the best spirit of agile development we would care about scaling it up when we get to that point.
  • Spring: nothing better for wiring all the rest together; also, Spring's declarative transactions via AOP enable us to use this aspect of J2EE without placing extra requirements on the container (the target platform is Tomcat, representing the lowest common denominator among Java application servers)
  • JSF: as the CRUD-type functionality requires sophisticated editing forms with in-line fields for dependent records, JSF and Facelets seemed the best technology for creating the edit forms and making them maintainable through using Facelet compositions; another aspect of Facelets is that this technology provides for using compositions for reusable parts of views, and for giving all the pages a common structure.

  • Spring MVC is a good supplement to the rather heavy view technology that is JSF: one might -- and usually does -- want to provide a simple controller or two for some special screens or features (AJAX/JSON, PDF, etc.) and not jump through JSF hoops to do that, while using a general-purpose MVC framework; Spring MVC can also provide for JSF navigation definitions' lack of scalability.

  • Spring Web Flow  is really something that one is almost forced to use given the previous choices (Spring + Facelets). JSF on its own is, sadly,  disappointing in everything except view composition mechanics. JSF/Facelets do not seem to scale as a complete view technology: its view-centric approach means it is unnecessarily difficult to provide for initialization, its navigation definition syntax is too verbose to maintain without heavy tools, and, finally, the view needs a mechanism for saving state that makes objects survive longer, than a single request-response, but not for the whole duration of a user session; a shopping cart is a typical example. Spring Faces and Spring Web Flow (SWF) provide for these shortcomings and add a lot more. That SWF is really solving a real life problem, rather than providing yet another idiosyncratic way of creating a Java web application, is indirectly confirmed by the fact that other frameworks aiming at reasonable completeness also provide work-flow features (I am thinking of JBoss Seam), and also do it with JSF/Facelets.

  • JAX-WS is simply the most modern -- and widely supported -- way of exposing services for integration. See one of the later articles on how to best expose Spring beans as JAX-WS services when using a minimal Servlet container such as Tomcat.

  • Maven is almost a must given the above mix of products. I have seen projects that were using Ant or other build tools being compelled to almost re-invent Maven just to maintain a dependency list: the number of libraries coming from different projects needed to use what has been listed above is many dozens, and each library comes in many different versions, some of which are not compatible with the versions that are required by other libraries. Apart from this -- already compelling -- need to be able to maintain a list of all the dependencies and dependencies of dependencies, Maven provides for simpler build definitions if the project is using a standard layout (and nothing would stop it from using that when starting from scratch). On top of that Maven provides a cheap solution for maintaining a firm-wide repository of code artefacts where each artefact (.jar, .war, ...) could be stored with a version number (so that several versions could be maintained) and also associated with source code archives (so that a framework library could be used by developers with source code for browsing and de-bugging). This last is again something that at least one of the major companies that I had been working for in the past had created in-house just to solve internal software distribution problems; Maven's repositories provide minimal working solution out of the box.

No comments: