Thursday, May 28, 2009

Netbeans + JBoss 4.2/5.x + IceFaces + Facelets: Gotcha

On creating a new WebApp project in NetBeans 6.x, I noticed a number of frameworks offered that support various technologies. Since I was prototyping a JSF-Facelets app, I chose the Facelets framework; as a result, NetBeans added the jsf-facelets.jar to my project libraries (which means these jars would be deployed as part of the warfile). I'll now file that decision in the "seemed like a good idea at the time" category: NetBeans users, here's a heads-up; please read on.

My goal was to compare RichFaces and IceFaces component sets (about which I'll post my findings later). Starting with IceFaces 1.8, I added dependencies as their documentation guided me for the JBoss 5.x app server - including the icefaces-facelets.jar, which I assumed was their own icefaces-specific layer above the standard Facelets distro. As it turns out, not so much.

On putting together a simple JSF page with Facelets tags, the page load yielded this exception:

java.lang.NullPointerException
com.icesoft.faces.facelets.D2DFaceletViewHandler.renderResponse(D2DFaceletViewHandler.java:268)
com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:153)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)

........

This seemed to point to a problem between IceFaces and Facelets, so my first instinct was to think that JBoss 5.x already had the Facelets classes loaded, and I was confusing things by adding my own version of these. As it turned out, I was on the right track...but more blind leads were to follow: in trying to reload the page, I got this exception:
java.lang.IllegalStateException: BaseClassLoader@144e022{vfsfile:}
classLoader is not connected to a domain (probably undeployed?) for class
javax.servlet.jsp.SkipPageException
This made me think that the removal of the Facelets jar was a mistake. Actually, no it was not; my mistake was trying to reload the page too quickly after redeploying. JBoss 5.0 takes a bit longer to complete a redeployment than I expected; had I simply waited another 5-10 seconds before reloading the page, I would have seen my original NPE problem solved instead of thinking I'd traded it for a different one.

What made this more confusing was that I tried the same webapp in JBoss 4.2, and had no problem at all. The IceFaces documentation around dependencies for JBoss 4.x vs 5.x is exactly the same; so it was mysterious why the webapp would work OK in 4.2 but not in 5.x.

After a bit more experimentation, I stumbled on the answers to all of the above:
  1. The standard Facelets jar should not be deployed when icefaces-facelets.jar is deployed; the latter appears to be an IceFaces-specific adaptation of the standard. This means NetBeans users should not choose the Facelets framework for a new WebApp project if they are going to be using Facelets with IceFaces.
  2. JBoss 4.2 classloading masks this issue by (apparently) loading the IceFaces version of these classes instead of the standard version, so things worked out just fine with 4.2.
  3. JBoss 5.0 loads the standard version of Facelets classes first (apparently), hence the problem.
  4. JBoss 5.0 redeployment of webapps takes a bit longer than you'd expect - in fact I noticed the TomcatDeployment mechanism undeploying/deploying my webapp three times before it finally stabilized, at which point page reloads will succeed without the misleading IllegalStateException.
  5. JBoss 5.1 redeployment goes by much faster; TomcatDeployment undeploys my webapp only once.

No comments:

Post a Comment