Comparing JVM Web Frameworks at vJUG

A couple months ago, I was invited to speak at Virtual JUG - an online-only Java User Group organized by the ZeroTurnaround folks. They chose my Comparing JVM Web Frameworks presentation and we agreed I'd speak yesterday morning. They used a combination of Google Hangouts, live streaming on YouTube and IRC to facilitate the meeting. It all went pretty smoothly and produced a comfortable speaking environment. To practice for vJUG, I delivered the same talk on Tuesday night at the Denver Open Source Users Group.

The last time I delivered this talk was at Devoxx France in March 2013. I didn't change any of the format this time, keeping with referencing the Paradox of Choice and encouraging people to define constraints to help them make their decision. I did add a few new slides regarding RebelLabs' Curious Coder’s Java Web Frameworks Comparison: Spring MVC, Grails, Vaadin, GWT, Wicket, Play, Struts and JSF and The 2014 Decision Maker’s Guide to Java Web Frameworks.

I also updated all the pretty graphs (which may or may not have any significance) with the latest stats from Dice.com, LinkedIn, StackOverflow and respective mailing lists. Significant changes I found compared to one year ago:

[Read More]

Posted in Java at Feb 06 2014, 10:54:17 AM MST 2 Comments

JSR 303 and JVM Web Framework Support

Emmanuel Bernard recently sent an email to the JSR 303 Experts Group about the next revision of the Bean Validation JSR (303). Rather than sending the proposed changes privately, he blogged about them. I left a comment with what I'd like to see:

+1 for Client-side validation. I'd love to see an API that web frameworks can hook into to add "required" to their tags for HTML5. Or some service that can be registered so the client can make Ajax requests to an API to see if an object is valid.

Emmanuel replied that most of the necessary API already exists for this, but frameworks have been slow to adopt it.

Hi Matt,

The sad thing is that the API is present on the Bean Validation side but presentation frameworks are slow to adopt it and use it :(

RichFaces 4 now has support for it but I wished more presentation frameworks had worked on the integration. If you can convince a few people or have access to a few people, feel free to send them by me :)

The integration API is described here. Let me know if you think some parts are missing or should be improved. We should definitely do some more buzz around it.

In the interest of generating more buzz around it, I decided to do some research and see what JVM Frameworks support JSR 303. Here's what I've come up with so far (in no particular order):

Struts 2 has an open issue, but doesn't seem to support JSR 303. Since I did a quick-n-dirty google search for most of these, I'm not sure if they support client-side JavaScript or HTML5's required. If you know of other JVM-based web frameworks that support JSR 303, please let me know in the comments.

Posted in Java at Mar 08 2011, 11:33:24 AM MST 4 Comments

AppFuse 2.1 Milestone 2 Released

I'm pleased to announce the 2nd milestone release of AppFuse 2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are Spring 3 and Struts 2.1. This release fixes many issues with archetypes and contains many improvements to support Maven 3. For more details on specific changes see the 2.1.0 M2 release notes.

What is AppFuse?
AppFuse is an open source project and application that uses open source frameworks to help you develop Web applications quickly and efficiently. It was originally developed to eliminate the ramp-up time when building new web applications. At its core, AppFuse is a project skeleton, similar to the one that's created by your IDE when you click through a wizard to create a new web project. If you use JRebel with AppFuse, you can achieve zero-turnaround in your project and develop features without restarting the server.

Release Details
Archetypes now include all the source for the web modules so using jetty:run and your IDE will work much smoother now. The backend is still embedded in JARs, enabling you to choose with persistence framework (Hibernate, iBATIS or JPA) you'd like to use. If you want to modify the source for that, add the core classes to your project or run "appfuse:full-source".

AppFuse comes in a number of different flavors. It offers "light", "basic" and "modular" and archetypes. Light archetypes use an embedded H2 database and contain a simple CRUD example. In the final 2.1.0 release, the light archetypes will allow code generation like the basic and modular archetypes. Basic archetypes have web services using CXF, authentication from Spring Security and features including signup, login, file upload and CSS theming. Modular archetypes are similar to basic archetypes, except they have multiple modules which allows you to separate your services from your web project.

AppFuse provides archetypes for JSF, Spring MVC, Struts 2 and Tapestry 5. The light archetypes are available for these frameworks, as well as for Spring MVC + FreeMarker, Stripes and Wicket.

Please note that this release does not contain updates to the documentation. Code generation will work, but it's likely that some content in the tutorials won't match. For example, you can use annotations (vs. XML) for Spring MVC and Tapestry is a whole new framework. I'll be working on documentation over the next several weeks in preparation for the 2.1 final release.

For information on creating a new project, please see the QuickStart Guide.

If you have questions about AppFuse, please read the FAQ or join the user mailing list. If you find bugs, please create an issue in JIRA.

Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing lists.

Posted in Java at Nov 15 2010, 03:28:57 PM MST 2 Comments

AppFuse 2.1 Milestone 1 Released

The AppFuse Team is pleased to announce the first milestone release of AppFuse 2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are Hibernate, Spring and Tapestry 5.

What is AppFuse?
AppFuse is an open source project and application that uses open source tools built on the Java platform to help you develop Web applications quickly and efficiently. It was originally developed to eliminate the ramp-up time found when building new web applications for customers. At its core, AppFuse is a project skeleton, similar to the one that's created by your IDE when you click through a wizard to create a new web project.

Release Details
Archetypes now include all the source for the web modules so using jetty:run and your IDE will work much smoother now. The backend is still embedded in JARs, enabling you to choose which persistence framework (Hibernate, iBATIS or JPA) you'd like to use. If you want to modify the source for that, add the core classes to your project or run appfuse:full-source.

In addition, AppFuse Light has been converted to Maven and has archetypes available. AppFuse provides archetypes for JSF, Spring MVC, Struts 2 and Tapestry 5. The light archetypes are available for these frameworks, as well as for Spring MVC + FreeMarker, Stripes and Wicket.

Other notable improvements:

Please note that this release does not contain updates to the documentation. Code generation will work, but it's likely that some content in the tutorials won't match. For example, you can use annotations (vs. XML) for dependency injection and Tapestry is a whole new framework. I'll be working on documentation over the next several weeks in preparation for Milestone 2.

AppFuse is available as several Maven archetypes. For information on creating a new project, please see the QuickStart Guide.

To learn more about AppFuse, please read Ryan Withers' Igniting your applications with AppFuse.

The 2.x series of AppFuse has a minimum requirement of the following specification versions:

  • Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)
  • Java 5+

If you have questions about AppFuse, please read the FAQ or join the user mailing list. If you find bugs, please create an issue in JIRA.

Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues.

Posted in Java at Nov 19 2009, 07:16:36 AM MST 8 Comments

AppFuse Light converted to Maven modules, upgraded to Tapestry 5 and Stripes 1.5

This past week, I stayed up a couple of late nights to do some of the AppFuse Light work I wrote about in October. I converted all web frameworks to Maven modules, as well as made them inherit from the appfuse-web project. Below is what the new module structure looks like:

New AppFuse Light Modules

At this point, the project is ready to import into AppFuse's SVN project. Here's a list of other changes I made:

  • Modules now depend on AppFuse's backend and allow you to use Hibernate, JPA or iBATIS as the persistence framework. Implementations for Spring JDBC, OJB and JDO have been removed.
  • Upgraded to JWebUnit 2.1, which now uses HtmlUnit under the hood and has much better JavaScript support. It also has Selenium support, but I've yet to try it.
  • Ajaxified Body integrated into all frameworks. You can easily turn it off by modifying the global.js file.
  • Prototype and Scriptaculous loaded from Google's Ajax Libraries CDN.
  • Upgraded to Tapestry 5. Mad props to Serge Eby and his tapestry5-appfuse project for showing me how to do this. Serge became a committer on AppFuse recently, so hopefully we'll continue to see great things from the Tapestry 5 support. I really like the clean URLs and minimum configuration required in Tapestry 5. It's testing framework is nice too, but I believe it could be improved.
  • Upgraded to Stripes 1.5. This was easy and painless. I'm definitely a fan of Stripes and look forward to reading the Stripes book on my bookshelf.
  • Dropped support for: Struts 1.x, WebWork, Spring MVC + Velocity.

If you want to try any of these applications, you can create archetypes using the following commands:

svn co https://appfuse-light.dev.java.net/svn/appfuse-light/trunk appfuse-light
cd appfuse-light/preferred-web-framework
mvn archetype:create-from-project
cd target/generated-sources/archetype
mvn install
cd ~/dev
mvn archetype:generate # The new archetype should show up as an option

Next steps include figuring out a way to flatten the inherited dependencies and plugins so archetype:create-from-project can create truly standalone projects. Please let me know if you have any questions.

Posted in Java at Dec 20 2008, 06:42:03 PM MST 9 Comments

Dojo/Comet support in Java Web Frameworks

Dojo Logo This week I'm doing a research project for a client. The main purpose of the project is to find out which Java-based web framework works best with Dojo and Comet. Here's the key requirement from the client:

It's all about Comet, we want Comet everywhere we can put it, but we want to isolate the icky bits of fiddling with pages with JavaScript. We're kind of wed to the Dojo implementation of the client-side bit, so we may as well use more of the Dojo widgets for a richer UI. For us, "works best with" needs to pay a certain amount of consideration to "fits naturally with", if you understand what I mean. I know that any framework that lets you spit out raw HTML will let you hand code in your Dojo / Comet, but that's certain to become very tiresome very quickly.

The candidate frameworks they asked me to look at are Wicket and Tapestry 5. They're willing to upgrade to Struts 2 since they're already using Struts 1. However, they don't feel that action-based frameworks naturally lead to rich UIs, so they'd prefer a component-based framework. They're currently using Seam for an administration-type application and feel it's too heavy for their customer-facing application.

Here's what I've found so far in my research. Please let me know if anything is incorrect.

  • Tapestry 5 doesn't have Dojo or Comet support (Prototype and Scriptaculous are the baked-in Ajax frameworks).
  • Struts 2 has old (version 0.4.3) and somewhat deprecated Dojo support. The developers seem to be in favor of removing it and promoting people hand-code Dojo instead. Struts 2 doesn't have support for Comet.
  • Wicket has support for Dojo 1.1 that includes Comet support. This was written by Stefan Fußenegger and posted to the mailing list last month. I e-mailed Stefan and asked him about documentation. His response: "I lost my ambition to document it properly since I didn't receive any feedback on the mailing list. :)"

At this point, it seems that if the client really wants to use Dojo, they should use Wicket, and possibly pay Stefan to document it properly. However, they're willing to consider other options, as long as they have Comet support.

One option I thought of is to use DWR and its Reverse Ajax/Comet support. Another option would be to add better Dojo support to Tapestry 5. However, I don't think this is possible since the Prototype/Scriptaculous code is generated by the framework and would likely require a changes to switch it to Dojo.

Are there any other Java-based web frameworks that support easily creating Dojo widgets and working with Comet? Keith Donald tweeted that Spring MVC has Dojo support. However, I believe it's only for widgets and it still requires you to write JavaScript. If your framework doesn't have Dojo/Comet support, how hard would it be to add it?

Update: I also posted this question on LinkedIn. Make sure and check my question for additional thoughts from folks.

Posted in Java at Dec 18 2008, 03:58:37 PM MST 19 Comments

Upgrading Hibernate to 3.4.0 and AppFuse for Tapestry 5

Last night I spent an hour upgrading AppFuse to Hibernate 3.4.0.GA. I tried the same thing a week ago, but failed miserably. When Hibernate Core Modules (3.3) (a Maven dependency howto) showed up on the Hibernate blog, I was re-inspired. I discovered some interesting things along the way (at least in my setup).

You need to use JBoss's Maven Repository
The latest Hibernate releases aren't in the central Maven repo yet. If they're not in there two weeks after the release, I doubt they'll be there anytime soon. Best to plan on adding http://repository.jboss.com/maven2 as a permanent repository. As a bonus, you can remove http://download.java.net/maven/2 since JTA is in JBoss's repo.

Javassist is not an optional dependency
If I remove the Javassist dependency, here's the error I get:

java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter

Seems reasonable right? What if I add in the dependency on Hibernate's cglib instead?

java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter

OK, so apparently you can't switch between Javassist and hibernate-cglib-repack as stated in Hibernate's Maven dependency howto. Of course, I do believe their instructions are correct, they just don't work in my setup. Versions I'm using: hibernate-core-3.3.1.GA and hibernate-annotations-3.4.0.GA.

Not including SLF4J is a bad idea
If you don't include a dependency on SLF4J (and you're using Spring), you get a nice cryptic error message.

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class 
[org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean]: 
Constructor threw exception; nested exception is java.lang.NoClassDefFoundError
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:115)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:61)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:877)
        ... 48 more
Caused by: java.lang.NoClassDefFoundError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:164)
        at org.springframework.orm.hibernate3.LocalSessionFactoryBean.class$(LocalSessionFactoryBean.java:174)
        at org.springframework.orm.hibernate3.LocalSessionFactoryBean.(LocalSessionFactoryBean.java:174)
        at org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean.(AnnotationSessionFactoryBean.java:64)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:100)

Hibernate's JPA now uses PersistenceException instead of EntityExistsException
In previous releases, Hibernate's ConstraintViolationException was wrapped in a javax.persistence.EntityExistsException. In Hibernate's EntityManager 3.4.0.GA, it's wrapped in a javax.persistence.PersistenceException.

Of course, these errors could be caused by Spring or Maven, but my hunch is they're more related to Hibernate and it's new more modular dependencies. You can view the full changeset for upgrading Hibernate 3.2.6.ga to 3.3.1.GA via FishEye.

Tapestry 5 version of AppFuse
In other AppFuse-related news, Serge Eby has created a Tapestry 5 version of AppFuse. You can see his alpha-level work in Google Code's tapestry5-appfuse project. I haven't had a chance to take a look at Serge's work yet, but I'm eager to do so. Hopefully we can get it back into the main project sooner than later. As far as Wicket and Stripes support, I haven't forgot about those - just having trouble finding the time and motivation to do the work.

Posted in Java at Sep 17 2008, 09:35:45 AM MDT 12 Comments

AppFuse 2.0.2 Released

The AppFuse Team is pleased to announce the release of AppFuse 2.0.2. This release includes upgrades to Spring Security 2.0, jMock 2.4, the ability to customize code generation templates and many bug fixes.

For information on upgrading from 2.0.1, see the Release Notes or changelog. AppFuse 2.0.2 is available as a Maven archetype. For information on creating a new project using AppFuse, please see the QuickStart Guide or the demos and videos.

To learn more about AppFuse, please read Ryan Withers' Igniting your applications with AppFuse.

The 2.0 series of AppFuse has a minimum requirement of the following specification versions:

  • Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)
  • Java 5+

If you've used AppFuse 1.x, but not 2.x, you'll want to read the FAQ. Join the user mailing list if you have any questions.

Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues.

Please post any issues you have with this release to the mailing list.

Posted in Java at May 11 2008, 11:25:40 PM MDT 4 Comments

All Java web frameworks should support hot deploy of a single class

In Anyone else using Groovy?, Tim Fennell (inventor of Stripes) raves at how much he likes Groovy now that it supports Java 5 features. He writes that Groovy might offer a solution to make development with Stripes faster:

The other thing I've been wondering about is that if there were enough demand for it we could try adding "improved" groovy support. E.g. throw your groovy actions under WEB-INF and we'll use groovy's built in stuff to do auto-reloading etc.

Gregg Bolinger responds with an excellent idea:

It would be really cool if Stripes could automatically discover and load changes to action beans (including new ones) without the entire app restarting, regardless of what the action bean is written in. But I realize that is a pretty tall order. :)

I agree that it might be a tall order, but I don't think it's impossible. In fact, I think all Java-based web frameworks should support hot deploy of a single class. We shouldn't have to buy JavaRebel to do this. It should be mandatory.

When an application reaches a certain size, the startup time can get pretty lengthy. This is lost development time. Furthermore, if any part of the development cycle takes longer than 15 seconds, there's a good chance developers will do something else (check their e-mail, move onto another task, etc.). Multi-tasking may be a good skill to have, but it's a horrible way to be productive.

Of the frameworks I'm familiar with, only Tapestry 5 and Seam support reloading single classes without restarting the whole application. Why can't the other frameworks "borrow" Tapestry 5's code? Maybe someone should just buy ZeroTurnaround and give away JavaRebel for free.

If I had one wish for 2008, it would be for all Java web frameworks to support this feature. Pretty Please?

Posted in Java at Jan 24 2008, 03:11:18 PM MST 21 Comments

AppFuse 2.0.1 Released

The AppFuse Team is pleased to announce the release of AppFuse 2.0.1. This release squashes a number of bugs and includes an upgrade to Spring 2.5. To learn more about Spring 2.5's features, see InfoQ's What's New in Spring 2.5: Part 1 article.

For information on upgrading from 2.0, see the 2.0.1 Release Notes or changelog. AppFuse 2.0.1 is available as a Maven archetype. For information on creating a new project using AppFuse, please see the QuickStart Guide or the demos and videos.

What is AppFuse? Click here to find out.

The 2.0 series of AppFuse has a minimum requirement of the following specification versions:

  • Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)
  • Java 5+

If you've used AppFuse 1.x, but not 2.x, you'll want to read the FAQ. Join the user mailing list if you have any questions.

Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues.

We greatly appreciate the help from our sponsors, particularly Atlassian, Contegix, JetBrains, and Java.net. Atlassian and Contegix are especially awesome: Atlassian has donated licenses to all its products and Contegix has donated an entire server to the AppFuse project. Thanks guys - you rock!

Please post any issues you have with this release to the mailing list.

Posted in Java at Nov 26 2007, 09:29:43 AM MST 4 Comments