Friday, May 29, 2009

I've begun my research into RichFaces, and decided to actually read their developer guide instead of just winging it. Sometimes I do crazy things, I know. Anyway, one of their initial suggestions was to get a plain JSF application in place and working, and I thought this was a decent starting point - that way, any anomalies could be more easily traced as I added RichFaces stuff.

So I put a plain vanilla Facelets-JSF app together (i.e., one that doesn't use a third-party component set, like IceFaces or RichFaces) , and got it working just fine on JBoss 4.2.2 (here I'm using Facelets 1.1.14). However, with my migration to JBoss 5.1, this rather dumb prototype stopped working, with this exception on initial deployment of the webapp:

SEVERE [compiler] Missing Built-in Tag Libraries! Make sure they are included within the META-INF directory of Facelets' Jar 15:35:25,318 SEVERE [viewhandler] Error Rendering View[/index.xhtml] java.lang.NullPointerException at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49) at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25) at com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95) at com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:524).............

On subsequent page loads, the "Missing Built-in Tag Libraries" message stopped appearing, but the NPE on NamespaceHandler continued to happen. Googling on the NPE was not entirely fruitful, but searching against the tag libraries problem led me to various known solutions; I addressed it by using the 1.1.15 version of Facelets.

Thursday, May 28, 2009

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:

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 classjavax.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:

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.

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.

JBoss 5.0 loads the standard version of Facelets classes first (apparently), hence the problem.

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.

Thursday, May 14, 2009

If you're setting up multiple instances of JBoss 4.2.x, you might run into this problem with the 3rd alternate configuration (ports-03).

There's a good writeup here for guidance on setting up multiple instances; I won't go into the motivation for doing it, let alone any details around how to do it here. I'll just assume you're reading this because you already know what I'm talking about - the topic at hand is already esoteric enough to require some prior knowledge, and I'd like to keep this post short.

When I set up a process to use the ports-03 binding, error messages appeared on deployment stating "Address already in use" for port 4446. Examining the binding-manager.xml file, I found that the service-config section that should override that default port was missing - and since my process using the default bindings was already running, the port conflict happened. Fix this by adding a copy of the "remoting connector" service-config section to the ports-03 configuration, changing the port to (e.g.) 7446, restart...and now you'll find that port 3873 has the same problem. Fix this by adding a copy of the "EJB3 Remoting Connector" section, changing the port to (e.g.) 4173, restart and you should be good to go.

Wednesday, May 13, 2009

Here's a collection of various idioms, patterns, tips, and etc. around JSF 1.2. It's a work in progress that I'll be adding to over time. So far, it's compiled by pulling stuff from the following websites - and I thank each of the authors for my reproduction of their content here:

If you name your Faces configuration file faces-config.xml and place it in your Web application's WEB-INF directory, then the Faces Servlet picks it up and uses it automatically (because it's the default). Alternatively, you can load one or more application-configuration files through an initialization parameter — javax.faces.application.CONFIG_FILES — in your web.xml file with a comma-separated list of files as the body. You will likely use the second approach for all but the simplest JSF applications (but be sure to not list faces-config.xml in that initialization parameter, or any registered phase listeners will fire twice).

If you need to explicitly manage the order in which properties are set:

The specification states that a JSF implementation must inject the dependencies of a managed bean in the order in which they are configured

Applications that are using JSF 1.2 can take advantage of the PostConstruct annotation. Below, the PostConstruct annotation instructs the JSF implementation to invoke the initialize method after the managed bean has been created.

A JSF implementation is not required to warn you about misspelled class names or cyclical references in managed bean declarations at startup, but both will result in a runtime exception. JSF 1.2 will warn you about duplicate managed bean declarations but 1.1 will not.

Use JSFUnit to help address these types of problems (although I've yet to try it, so I'm unclear about the status of JSFUnit static analysis features, but it appears that the runtime testing is GA). You can also avoid some of these problems with annotations libraries found in Seam or Shale.

process events: Ensure any event listeners are called - can declare Response Complete to short-circuit lifecycle. For example, an application might need to redirect to a different web application resource, such as a web service, or generate a response that does not contain JavaServer Faces components. In these situations, the developer must skip the rendering phase by calling FacesContext.responseComplete.

When the life cycle handles an initial request, it only executes the restore view and render response phases because there is no user input or actions to process. Conversely, when the life cycle handles a postback, it executes all of the phases.

You can install PhaseListeners into the Lifecycle to do whatever you want before or after each or every phase. PhaseListeners are registered in a JSF configuration file:

The presence of this JNDI entry will cause the state to be encrypted using the specified password...this isn't the most secure way of conveying a password, however, this cannot be accessed easily without having code executed on the server side.

Monday, May 11, 2009

It's late on a Friday and I've just solved a JSF headache, so I'm going to quickly write this up while it's still fresh in my mind (the solution, not the headache).

You may have stumbled onto this message if you're developing in JSF or just vanilla JSP:

#{..} is not allowed in template text

When you Google this phrase, you'll find various chunks of advice around versions of JSP, deferred expressions and the Unified Expression Language that comes with JSP 2.1. In particular, this reference appeared to have the definitive fix for my problem: either change the "#{" to "${", or backslash-escape the "#{" sequence, or change a setting to allow deferred syntax as literal. Now, any or all of these solutions might work for you, depending on your context; but I write this up because none of them worked for me.

What I have is a web application developed with JSF 1.1 that had used JSTL 1.1, but that then got deployed into a Java EE 5 environment which provides JSF 1.2 and JSTL 1.2. Many of you already know where this is going. But for my own future reference and possibly your amusement, I'm going to write it up anyway.

I changed all occurrences of #{ to ${, and knowing that Java EE 5 servers already supply the correct JSTL 1.2 version, I removed my webapp's private copies of jstl.jar and standard.jar (vestiges from when they were needed, with J2EE 1.4 servers), but now I get this error message:

According to TLD or attribute directive in tag file, attribute rendered does not accept any expressions

So the syntax change was a head-fake, at least in my case; I can't explain why. You are invited to chime in if you understand it. I was referred to one useful discussion that contains various suggested solutions and references various other threads, and it got me on the right track. Here's what I ended up doing: first, change the ${ back to #{, since really getting the incorrect JSTL version out of the way is the true fix. There is also an EL expression factory workaround discussed in that thread which was applied to my deployment descriptor.

But, here's where it gets interesting (as if it isn't already drop-dead compelling, right?) -- although removing the JSTL 1.1 stuff, applying the DD workaround and reverting back to #{ syntax should have cured all my problems, now I get an EL parsing error concerning this particular attribute construction:

This is a boolean expression managing a text value that must change depending on the state of a given backing bean property; this had worked just fine in my JSF 1.1 deployment, but now it's no good. The error reads something like this:

Without belaboring the point - since I have a headache from all the different things I tried - I'll just admit it: I took the inelegant way out and used two panel-grouping blocks, each with its own rendered-if attribute, to fix this problem (I'm using tags from the Woodstock JSF component set):

Using JSTL IF and WHEN testing is just as ugly, but at least it fails to work. The JSTL expressions get evaluated too soon relative to the JSF lifecycle, i.e. the IF and WHEN always yield false since they're evaluated before the backing bean property gets its value set as needed.

I didn't do any research to understand why the inline boolean expression in JSF 1.1 caused a parsing error in JSF 1.2 (or maybe it's a JSP 1.2 vs JSP 2.0 thing...hey, probably it's JSTL 1.1 vs 1.2...isn't web-tier fun?). So while I've solved the immediate problem, I've left plenty of room for colleagues to elaborate and, frankly, to correct me where I'm misleading. Like I say, it's late on a Friday and sometimes I do as little as necessary to get from A to Z. If anyone has additional insights around what's discussed here, you are invited to share.

Welcome to the Perimeter Sweep Blog

My blog is largely intended to be a placeholder for topics involving software development - architecture, technology drill-downs, best practices, various solutions, workarounds, gotchas and the like - things that will remind me what I've learned over time. If it helps you out also - all the better.

Subscribe To This Blog

About Me

I'm a Senior Software Engineer, an avid runner, and formerly a professional musician...currently the proud father of a super-tyke, raising two Siberian Huskies and married to my best friend. Life is good.