I have gathered some experience on this topic, as I started to program on a new project in November. The project is in a late stage now.
For me, the following design guidelines were important:
- Use a modern technology stack that is both fun to use and will be in general use in future.
- Reduce the number of project artifacts - use annotations/Java code where it makes sense, omit XML.
- Use frameworks that are open-source
- Have an active community
- Are not alpha stage
- Are lightweight
- Avoid duplication of concepts
- I can explain the concepts in it to my two fellow developers, who - despite being good programmers - have never used dependency injection (DI) or web frameworks.
- Can serve as a techological basis for future projects
Google Guice as a DI container was an obvious choice - clearly the most well-thought DI contianer, with brilliant developers and a good community. It fulfills all the bullet points mentioned above.
So I set up my basic techology stack. Started with Guice, added Hibernate for persistence (along with warp-persist and warp-servlet). Then I wrote some basic DAO that selects something.
Then I tried to do the following: added a different web framework on top of that.
- XSLT with xStream using regular HTTP servlets
- JSF- MyFaces
- Apache Wicket
- warp-widgets
I created a simple page with a table, populated by the DAO, headers and a textfield with all four frameworks.
These were my findings when comparing the four frameworks.
XSLT and XStream is kind of a hardcore-approach. It's not really a framework, but a viable completely stateless techology for high-performance applications. This was by far the fastest way of serving the test page. In debug mode, 3 ms on localhost versus about 30-50 ms with the other framworks.
Guice integration was relatively smooth and good using warp-servlet which enabled me to inject into servlets and injects httprequest, httpresponse, session in other objects, without passing them around. Disadvantages: no community at all, since I am the only person who would consider this stack. - no ready-to-use components.
Then I took a look at JSF and Guice: it is of course possible to put the injector in the servlet context and use guice as a service locator. With the straightforward approach it's impossible to inject backing beans somewhere else. Using a custom variable resolver solves this partially, but then you lose all IDE integration in your JSF files plus you will have to use ugly FQN for your backing beans, or build a string->Guice key mapping somewhere. Both are ugly as:
- Advantages: good community, many developers in the job market (no criteria for me). You won't get fired for chosing JSF if something goes wrong.
- Disadvantages: brings its own Inversion of control (IoC) mechanism which clashes conceptually with guice.
warp-widgets: I created my simple example using this for fun; it's early alpha stage. It was nice to use and its components are easy to implement and reuse by myself. It aims to provide typesafe HTML with perfect Guice integration. Since it looked like it had only one active developer back then, who is now propably working on Guice 2.0, I would say the community is nearly non-existent. It worked like a charm, was reasonably fast, but I would have been alpha tester. That was simply too risky for me to consider it for a commercial project.
Apache Wicket: this project first suprised me with wicket-ioc and wicket-guice coming together in the core download. Constructor injection in web pages is not possible, only setter+field. Injection in Wicket web pages is easy, just add @Inject
to the fields you want to fill - but you're not supposed to understand how it works in background. Tricky stuff happening. Injection of web pages is theoretically possible - but I have not used it once, since this makes it impossible to use mounted URLs, plus it will mess with the persisted/serialized state.
Injected members of classes are dealt transparently with web page serialisation, which is necessary for enabling browser-back support. Wicket uses zero external artifacts - just a little configuration of the URLs in a application class. So all configuration is done in Java - which fits the Guice model well. Clear seperation of HTML and Java. It's open-source just like the majority of the components that are numerous and of good quality. It's around since 2005(?) and is a top-level Apache project. Although it's a feature-rich framework, its API is reasonable compact (all core classes fit in a single JPEG on my screen). Unlike others, it does not bring a IoC mechanism of its own, but rather thinks of IoC as a service that can be provided by Spring Framework, Guice, etc. and that philosophy makes it superior w.r.t. Guice integration.
Did I mention really smart and easy Ajax support?
Frameworks not deeply evaluated: tapestry5 - brings its own IoC.
Seam: not a framework on its own, but a meta-framwwork which normally comines Spring, JSF. Hibernate. (Though Spring may theoretically be replaced by Guice.)
Summary: of the evaluated framworks, Apache Wicket was the clear winner - with respect to Guice integration + all other criteria mentioned.
Besides us two, some other people have had this problem before.