JSF 2 On The Road

December 17, 2009

I normally don’t do all that much work-related traveling.  A couple of trips to Oracle HQ every year.  A conference here and there.  Manageable.

The last two months have been quite a break from my typical travel pace.  I have attended four conferences in three countries in order to present seven times (plus a BOF and a panel) on four different topics with three different co-presenters. What could possibly make me abandon my co-workers, friends and especially my wife for such an extended period of time you ask?  Why, JSF 2 of course!

Heh. Not sure whether that came across in quite the right spirit.  I can imagine the tweets now:

JSF EG member admits that JSF 2 causes you to neglect all of your worldly responsibilities. #jsf #fail.

Perhaps I should clarify. :-)

The arrival of the JSF 2.0 specification back in June was a huge step forward for the world of JSF. However, the specification is only a starting point. We won’t get very far without an implementation of the spec. (Mojarra shipped its production release in October. MyFaces 2.0 work is underway.)  We also need compliant versions of widely used component sets/extensions. (All of the major component/extension vendors are already focused on this and committed to supporting JSF 2.)  And finally, we need to spread the word: JSF 2 is here!

Which brings me to the subject matter of this blog: my recent travels!

Oracle OpenWorld

As just about everyone in the Oracle universe knows, October is OpenWorld season.  Somehow after 16 years at Oracle I still had not attended this conference.  As luck would have it, this year my opportunity to attend finally arose.  Jim Driscoll and I secured a spot for a joint presentation on JSF 2. Jim and I had worked together on JSF 2′s Ajax support, but only over email and conference calls, so I was happy to finally have a chance to spend some time together in real life.  Or, as close to “real life” as Moscone during OOW can be considered anyway. ;-)

Our Complete Tour of the JavaServer Faces 2.0 Platform session (slides) was inspired by a webinar that JSF 2 co-spec lead Ed Burns gave back in May. Of course, with so many new features in JSF 2, a truly “complete” tour is a challenge. Jim and I hit the highlights, covering Facelets, composite components, Ajax, view parameters, system events, resource loading, partial state saving, etc… (If these topics aren’t ringing any bells for you, you might want to check out What’s New In JSF 2?.)

In spite of some pre-talk nervousness (me, not Jim), the talk went smoothly. The audience seemed engaged and asked good questions (component compatibility, session state footprint, view actions). Sitting front and center: Cay Horstmann, prolific author and blogger. How exciting to have the author of both Core Java and Core JavaServer Faces (JSF 2 edition coming soon) sitting in on your JSF talk! Cay even included some nice comments on our talk in his write up of OOW Day 1.

Jim and Andy at OOW

Jim and Andy at OOW

Unfortunately I didn’t get to spend as much time as I would have liked at Moscone. However, I did have the pleasure of seeing my Oracle colleagues Matthias Wessendorf and Frank Nimphius present on our project, ADF Faces.  Matthias and Frank had an excellent rapport and presented the subject matter in a fun, compelling manner.  The audience was clearly intrigued.  The demos of the ADF Faces table component (which supports data virtualization and Ajax-based scrolling) and active data (our Comet/push solution) were particularly well received.

We capped off my OOW experience off with a visit to the Howard Street tents followed by dinner with my Oracle cohorts plus Jim.  All in all, a great start to my JSF 2 tour!

W-JAX

After a couple of weeks of down time (and by “down time”, I mean madly working around the clock in a desperate attempt to finish preparation of three presentations that I would be giving at upcoming conferences), I was off to Munich for W-JAX.

My W-JAX plans had taken shape months before, roughly around JavaOne 2009.  Both Matthias and I were in attendance and took advantage of the lovely Bay Area weather for a side trip down to Santa Cruz.  Along the way I described some presentation ideas to Matthias.

Andy and Matthias in Santa Cruz

Andy and Matthias in Santa Cruz

As luck would have it, Matthias was looking for speakers for the W-JAX JSF Experts Day.  After some discussion between Matthias and the conference organizers, we had two session slots lined up for my first ever European conference.

First up was a web framework comparison talk titled “Component Framework Primer for JSF Users” (slides). I decided to focus on three web frameworks: JSF, Wicket and Tapestry, as these frameworks share characteristics (server-centric, component-based) that make for interesting comparisons. I provided a quick introduction to each framework and then compared key functionality including: page definition, binding, event handling, Ajax, navigation, input processing and custom component development. The presentation contained code snippets for each topic as well as commentary on the solutions provided by each framework.

An obvious difficulty when performing any sort of comparison that involves competing technologies is doing so in an objective manner. This is especially true when the person doing the comparing is an advocate for one of the technologies being compared! It would have been easy to use this time to promote JSF by fixating on negative aspects of the other frameworks. (All frameworks have flaws of course.) However, this approach didn’t feel compelling to me. Instead I decided early on to use this as an opportunity to understand the strengths of each framework. Admittedly, my reasons for doing this were selfish. I was hoping that by looking at what Wicket and Tapestry do well rather than where they fall short, I might take away some ideas for ways in which we can further improve JSF in the future.

Forcing myself to learn two other web frameworks turned out to be a great experience and, well, fun. I found it fascinating to see how the frameworks approached problems from different angles. (I’ll save more detailed thoughts on this for another blog post.) I am not sure whether everyone in attendance found this topic quite as fascinating as I did (I am a framework geek after all), but my audience did seem to enjoy the quick tour of these three frameworks.

My second W-JAX presentation, “JSF Component Behaviors – Deep Dive” (slides) was on a more inward looking topic. The JSF 2 component Behavior API grew out of our effort to integrate Ajax into the JSF 2 specification. The Behavior contract provides the mechanism by which Ajax “behaviors” are attached to JSF components. By generalizing this contract we hoped to facilitate attaching other types of client-side behaviors and as such not limit our solution specifically to Ajax. This talk explained the Behavior model in detail and walked through the steps/code involved in implementing Google auto suggest-style functionality on top of the new JSF Behavior contract.

I thoroughly enjoyed researching/giving this talk as well. I felt like it had a good mixture of commentary, code and, a first for my talks: a demo! Fortunately the demo gods smiled on me: my auto suggest implementation was working in fine form. :-)

Outside of my talks, I had a wonderful time at the W-JAX conference and even made it out of the conference hotel once or twice to experience a bit of Munich. See What Do JSF Guys Do In Munich? for details.

Hofbrauhaus

Hofbrauhaus, Munich

I always enjoy spending time with Matthias, but it was especially fun to hang out together in Germany, as all of our past adventures together had been in the US.  It was also a chance to reunite with my fellow EG member Kito Mann, who I have had the pleasure of meeting at past conferences.   I was particularly excited to finally meet EG member Martin Marinschek.  Martin and I had worked closely on a number of issues during my tenure on the EG, and I am always impressed by Martin’s technical prowess, API design skills and contributions to the spec.  I was thrilled that we were able to spend time together in Munich and feel like I have found a kindred spirit and friend.

Devoxx

After spending Saturday in Munich, I was off to Antwerp for my first ever trip to Devoxx, where I would meet up with my EG colleagues Dan Allen and Pete Muir (of Red Hat/JBoss) to present on JSF 2.

When Dan and I first discussed the idea of a joint, cross-company presentation on JSF 2, Dan proposed that we go for a (3 hour) university session.  3 hours?!  Yikes!  As anyone who knows Dan knows, when Dan is passionate about an idea, his enthusiasm can quickly become contagious.  I reluctantly agreed, but soon found myself excited by the prospect of an extended session.  In the end, the university session approach worked out perfectly.  Or, I should say almost perfectly: we ran out of time for questions!  My guess is that we could have filled a four hour session.  Fortunately, we had a follow up BOF scheduled for the same evening.

One reason that Dan pushed for the university session is that it would give us time to cover JSF 2 functionality in more detail than past JSF 2 overview presentations (including the one that Jim and I gave at OOW).  However, there was another opportunity that the three hour session would provide.  Dan, Pete and I agreed early on that we wanted to use this time not just to inform the community of new features, but also to accomplish two other goals:

  1. We wanted to use the (big) stage at Devoxx to engage the community and encourage community participation in JSF.
  2. We wanted to not just look back at the problems solved by JSF 2, but also look forward and see how we can build on top of the progress provided by JSF 2 to further improve the platform.

Thus, the long debated title of our talk: JSF 2 and beyond: Keeping progress coming (slides).

To get a jump start on our goal of getting the community involved in shaping the future of JSF, we decided to take advantage of a tool that would allow for some immediate interaction: Twitter! At the start of our presentation we encouraged our audience members to tweet any thoughts/questions that they might have on our presentation or more generally on the future of JSF. We recommended that tweets on this topic include the “#jsf2next” tag to make it easy to track these down. While we were first inspired to adopt this convention for our presentation, we quickly realized that this solution had utility beyond the scope of any one presentation or conference. Tweets on #jsf2next are still coming in weeks after our talk. Keep the tweets coming!

We ended up splitting our content into three major sections, in the spirit of MVC.  First, I covered the “view” portion of the stack, including discussion of Facelets, component development, Ajax support, Behaviors and state saving.  Dan then covered “controller” topics: navigation handler enhancements, improved GET support, view parameters, bookmarkable URLs, resource handling.  Pete covered the “model”.  As the project lead for Weld, the reference implementation for JSR-299 (Contexts and Dependency Injection for JEE), Pete had quite a lot to say on component models.  This turned out to be a very timely topic, as the JSR-299 final ballot was underway (now approved!) as we were speaking.

Dan, Andy and Pete at Devoxx

For each section, we examined historical difficulties, looked at how JSF 2 and related JEE specifications (JSR-299, JSR-303) have helped to solve these problems and also discussed our thoughts on areas that could use additional attention in the future.

Dan wrapped up our talk with a section on community. Increased inclusion of the community in the development on JSF is a cause that Dan has championed for at least as long as we have known each other. Of course, a pre-requisite for increased involvement is that people need to know how they can participate. Dan tackled this topic, describing our goal of using the infrastructure (forums, wikis) provided by the (recently overhauled) JCP site for EG/community interaction. I was proud to share the stage as Dan sincerely encouraged our audience to get involved!

Our talk flew by. Aside from running out of time for questions (sorry), I was happy with how smoothly the talk went. We did end up with good attendance/participation and plenty of time for questions at our BOF that night, which also included JSF co-spec lead Roger Kitain.

JSF 2 And Beyond Audience at Devoxx

JSF 2 And Beyond Audience at Devoxx

As it turns out, we received some good feedback/coverage of our talk, including the first ever French-language review of any talk that I have been involved in (as far as I know anyway):

Devoxx – Jour 1 – JSF 2

Some more comments here:

Devoxx Day 1: University Day 1

Dan shares some thoughts here:

JSF 2 in the spotlight at Devoxx 09

And some additional comments here:

DEVOXX UNIVERSITY 2009

The money quote:

The presentation given by Peter Muir was the best of the 3.

Ha. I thought Pete did a great job too!

Seriously though, I was excited just to be speaking on the same stage as such talented and accomplished speakers as Dan and Pete. If only Pete had been a bit more clear about expressing his enthusiasm for CDI over managed beans. ;-) Hopefully we did both Red Hat and Oracle proud and provided some new insight into JSF 2 features, future and community to Devoxx.

While speaking at Devoxx may feel like playing on Super Bowl Sunday, the Devoxx conference itself still has a down to earth, grassroots feeling.  I suspect that this is in large part due to the passion and vision of Stephan Janssen.  Despite having to run a conference of thousands of attendees, Stephan was one  of the very first people that I met as I walked through to doors of the Metropolis.  Stephan took a moment to  make me feel both welcome and also excited about the upcoming event.  What a great way to get things started.

There were too many Devoxx moments to describe them all in detail here, but a few highlights:

  • Getting to meet and hang out with my Oracle colleagues Maiko Rocha and George Maggessy.
  • Watching Steve Harris give his keynote, demoing WebLogic while wearing a Glassfish shirt.
  • Attending the speaker dinner at a churrascaria in downtown Antwerp. What an excellent (and delicious) event! Though, a lesson that we learned that evening: Dan and I probably should not be allowed to sit at the same table, unless, of course, you want to talk JSF/JCP! ;-)
  • Meeting up with David and Jevgeni from ZeroTurnaround to discuss JRebel support for JSF. (Which somehow lead to a brief discussion of Operation Ivy. How cool is that?)
  • Catching up with ex-Oracle colleagues Peter Lubbers and Jonas Jacobi who are now doing their own real time streaming thing at Kaazing.
  • Bumping into Sebastian Hennebrueder, author of JSF 2 – evaluation and test followed by an impromptu meeting with Sebastian, Dan, Pete and Roger to discuss ways to address issues raised in Sebastian’s article.
  • Taking a few minutes here and there to be mesmerized by the #devoxx twitter stream display. (C’mon, you know you did it too.)
  • Sitting down at a table to catch up on email and looking up to see that I am sitting directly across from James Gosling.

Which, btw, presents an interesting dilemma not untypical of Devoxx… If you sit down across from James Gosling as he is typing away on his laptop, do you interrupt him to say hi, or leave James alone to his thoughts? In the 30 minutes that I sat there, at least 6 people decided on the former course. In every case, James was exceedingly friendly, attentive and gracious. Wow. Okay, so, yes, I eventually did introduce myself to James. I did my best to keep it short and avoid reverting into Chris Farley interviewing Paul McCartney form. (Andy: “And remember when you invented Java? That was AWESOME!”. James: “Umm… who are you again?”.)

On my last evening in Antwerp, I tagged along with the JBoss crew (and I mean crew – there must have been 30 people!) to dinner and drinks in Antwerp center.

Antwerp

JBoss Night Out in Antwerp

Yes, there was more JSF/JCP talk between Dan and myself, but I also got to spend time with other JBoss team members, including Manik Surtani, Max Anderson, Emmanuel Bernard and Rodney Russ.  It was a memorable evening and a great way to bring my Devoxx experience to a close.  (Thanks for dinner JBoss!)

JSF Summit

After a quick but much needed break for Thanksgiving, I was back on the road again. My next stop was the JSF Summit and Rich Web Experience in Orlando.  While JSF Summit was the smallest conference of the four that I attended, it held an excitement for me that was different from any of the other conferences.  This was the first JSF-focused conference that I had ever attended!

I had the honor of presenting three times to the JSF Summit audience. Dan and I gave an abbreviated version of our “JSF 2 and beyond” talk in one of the opening time slots.  Once again we covered view, controller, model and community. Later that day I presented an extended version of my “Component Framework Primer” talk. While I appreciated having an extra 30 minutes (90 minute sessions), I also realized that perhaps two hours would have been more appropriate for this topic. On day two I gave an extended version of my “Behaviors Deep Dive” talk.

The JSF Summit experience was, in short, amazing. There was not a session that I didn’t want to see.  Just about every session that I attended was packed with members of the EG and other recognizable faces from the JSF community.  At OOW I had the honor of presenting with Cay Horstmann present.  At JSF Summit I presented to his partner in crime/co-author, David “Mr. Harrison Ford of JSF” Geary. And not just David… Looking around in the presentations that I attended/gave, I would find familiar faces like Ed Burns, Kito Mann, Andy Bosch, Lincoln Baxter III (PrettyFaces), Cagatay Civici (PrimeFaces), Martin Marinschek (MyFaces), Jay Balunas (JBoss/RichFaces), Max Katz (Exadel/RichFaces), Ted Goddard (ICEfaces), Jim Driscoll (Mojarra) and Neil Griffin (Liferay).

But it wasn’t so much the presence of EG members and colleagues that made this conference special.  The conference’s explicit focus on JSF lead to a unique interaction between speakers and attendees. Kito summed it up perfectly with the following tweet:

It’s so satisfying to see the speakers and audience interacting at #jsfsummit. Excellent sessions!
7:09 AM Dec 4th from TweetDeck

I couldn’t agree more.

Of the talks that I attended, it is hard to pick a favorite, but two talks that stand out in my mind are Cagatay’s Rapid RIA Development with PrimeFaces talk and Lincoln’s PrettyFaces – Harness SEO, Improve User Experience, Ease Development talk.  These talks both covered exciting new additions to the JSF ecosystem.  It was fun to watch the audience’s extremely positive reaction to Cagatay’s impressive demos, especially considering that the audience contained several members of competing component vendors.  Lincoln also did a great job presenting, and it was a joy to see JSF and pretty URLs together at last.

One of the highlights of the conference for me was sitting in on a JSF expert panel.  The panel demonstrated something that gets to the heart of what makes me proud to be part of the world of JSF. Sitting on the panel with me were members of competing frameworks, heck, competing companies, yet any dissension that might exist between the various representatives was left behind. It’s not every day that you see a meeting of the minds between members of the JBoss Seam (Dan Allen) and Spring (Jeremy Grelle) teams.  It is certainly unusual to see these two organizations sharing a panel in support of the same technology! In a similar vein, the panel had representatives from ICEfaces (Ted Goddard), RichFaces (Jay Balunas) and Trinidad/ADF Faces (me).  Again we see members of competing technologies putting aside differences in order to focus on a common goal. I have seen this sort of thing again and again over my time on the JSF 2 expert group.  JSF Summit exemplified this spirit.

ICEfaces (Ted), RichFaces (Jay), Trinidad/ADF Faces (Andy) and PrimeFaces (Cagatay)

ICEfaces (Ted), RichFaces (Jay), Trinidad/ADF Faces (Andy) and PrimeFaces (Cagatay)

There were too many great moments at JSF Summit to document them all, but a few other quick recollections:

  • Taking a tour of JSF Around the World featuring tour guide Ed Burns.
  • Sitting in on an excellent face to face “extended” EG meeting (agenda), with discussion of community, cross component set compatibility, performance and jsf2next.
  • Finally meeting my Oracle/JSF 2 EG colleague Michael Freedman and getting a crash course in JSF/portlet integration from the master of this topic.
  • Witnessing Rickrolling in action, as Lincoln demonstrated the need for user-understandable URLs while simultaneously showing off his best Rick Astley-inspired dance moves. Go Lincoln!!
  • Seeing some new faces, making new connections and having good talks with the likes of Steven Boscarine, Matt Drees, Micha Kiener, and Ian Hlavats.
  • Monitoring Dan’s progress as he navigated his way through 8 talks in 3 days. Somehow Dan never seemed to lose any steam! (And I thought that my 3 talks in two days was a feat.)
  • A couple of late nights at the Thirsty Fish with the JSF crew. (Next time somebody really needs to take a picture or two!)
  • Watching my Oracle colleague and long time friend Max Starets hang out with the JSF gang, seemingly very much at home in this group.

Dan has captured many more thoughts on JSF Summit here:

JSF Summit 2009 postback

Jay posted some interesting thoughts too:

JSFSummit – a Component Libraries Point of View

Lincoln’s JSF Summit story is here:

What a wild ride – My journey through OpenSource / JSF

One last, but very important highlight for me…  JSF Summit saw the introduction of a new community hub for JSF users: www.javaserverfaces.org.  This site is the work of JSF community activists Lincoln Baxter III, Dan Allen and Kito Mann.  Well, I helped a bit too, but mostly just by providing words of encouragement. Lincoln explains to purpose of this site more clearly than I can:

JSF2 – Engaging the Community

I am already a javaserverfaces.org user. Been hitting it on a daily basis for easy access to the JSF 2 doc set. I am very much looking forward to watching (and hopefully helping) this site grow!

Looking Back

Okay, so, yes, I consider myself amazingly lucky that I was able to attend/speak at so many conferences in such a short period of time.  Each conference was special in its own way, and I would love to attend any of these conferences again in the future.

While the conferences may be over, the spirit of these conferences is still going strong. The JSF expert group mailing list has seen a tremendous spike in traffic as EG members start hashing out jsf2next ideas. If you’ve been waiting for an opportunity to make an impact on the future of JSF, there is no time like the present. Check out the www.javaserverfaces.org for tips on how to get involved!

If you attended any of my talks along the way, thanks for coming! I thoroughly enjoyed presenting to you. I hope you found something useful in what I had to say.

If on the other hand, you are my manager, co-worker, family member, friend or, most-importantly, wife: Thank you for your support and patience.

What Do JSF Guys Do In Munich?

November 14, 2009

The same thing as everyone else apparently: drink beer!

Cheers From Munich

Kito, Matthias, Andy

I had the honor of attending/presenting at W-JAX 2009 in Munich this week. The highlight of the conference for me was of course getting to spend time with friends/colleagues old and new.

Three things that I learned while in Munich:

  1. Hanging around Matthias is a great way to meet interesting people.
  2. When in Munich, try the grilled pork  knuckle at Haxnbauer.
  3. A good presentation can work even if you don’t speak the language.

On Friday I sat in on (fellow EG member) Martin Marinschek’s talk titled “Wie Sie Ihre JSF-Anwendeng garantiert nicht produktiv bekommen”, which covered 17 tips for how *not* to build your JSF application. Martin had a light hearted (but informative) tone that the audience clearly enjoyed.  I had a blast trying to guess what the tips were based on keywords/APIs in the slides. :-)

On Thursday evening a group of us JSF folks ventured out of the hotel (yay!) and into Munich city center for dinner. We avoided the Hofbrauhaus (worried it would be a bit too touristy/loud) and instead ended up at the Schneider-Weisse beer house.

JSF In Munich

JSF Munich Crew: Kito, Matthias, Andy, Thomas (of JSF/Ajax Matrix fame), Martin

We ate roast pork shoulder, had a few drinks and discussed politics, religion, the fate of mankind and all other matters philosophical and metaphysical.  Not a word about JSF the entire evening!

Okay, actually, no… that is a total lie.  Either way, it was a wonderful evening and I am so happy that I had the chance to be there.

Thanks Matthias for helping to bring me to W-JAX, for being a great translator, host and friend, and also for buying me my first beer in over 20 years!

Tomorrow morning I am off to Antwerp to meet up with Pete Muir and Dan Allen.  We will be discussing JSF 2 future/community in our university session at Devoxx on Monday:

JSF 2 And Beyond: Keep the progress coming

If you are going to be at Devoxx and you are even remotely interested in JSF, you won’t want to miss this talk. Hope to see you there!

Anyone Have An Oversized Foam Cowboy Hat That I Can Borrow?

September 13, 2009

I couldn’t resist posting this screen shot from the Devoxx 2009 speakers page:

Need Foam Cowboy Hat

Okay, yes, I admit, I am a Java Posse geek. So I was pretty tickled to see this particular configuration of speakers. Clearly it is time for me to get a new headshot. If only I had one of those cool foam cowboy hats! :-)

(More info on my upcoming talks coming soon!)

What’s New in JSF 2?

July 31, 2009

With so many sources of information available on JSF 2, why bother with another overview? After all, this ground has already been covered quite extensively:

One problem I have been facing is deciding where to point my Oracle colleagues who are interested in a quick introduction to the JSF 2.0 feature set. The spec contains all of the information, but that’s some pretty heavy reading. The blogs do a phenomenal job of covering specific features but do not provide a big picture overview. The Webinar provides the big picture overview, but some folks might prefer reading over listening/watching. The slides also provide an overview, but I wanted something with more prose than bullets.

So, on the theory that more is good, and since I could not find quite what I was looking for, I decided to spend some time writing up my own take on the new JSF 2.0 feature set. Of course, I borrowed from all of the above sources while working on this, so many thanks to my JSF colleagues for making my job easier!

Note that I do not attempt to cover these features in extreme detail. This is just an overview. However, each section includes links to more detailed information where available, so please click through if you do not find the level of detail that you need here.

Contents

View Declaration Language and Facelets

Not to knock JSP, but even JSP champions must admit: JSP as the primary view technology for JSF has not been a walk in the park. The problems have been discussed for years, dating back to the now classic Improving JSF by Dumping JSP, published back in 2004 just months after the JSF 1.0 spec was released. As of JSF 1.2/JSP 2.1, several of the key issues have been addressed. However, the JSF/JSP combination certainly has room for improvement.

The JSF community has not been sitting still. Several JSF-optimized alternatives to JSP have emerged, including Apache Shale’s Clay (now retired), JSFTemplating and Facelets. However, the lack of a standard solution remains a sore point for JSF users. JSF 2.0 recognizes the need for a standard alternative to JSP and addresses this by taking two steps.

First, JSF 2 provides a generic foundation for integrating view declaration languages into the JSF runtime environment. The ViewDeclarationLanguage API defines the contract through the JSF runtime interacts view declaration language implementations in order to complete tasks such as building up the component tree. This contract allows framework authors to define their own view declaration languages and integrate these with JSF in a standard way.

Second, JSF introduces the first standard non-JSP view declaration language: Facelets! JSF 2.0 includes a re-purposed version of the Facelets 1.x API/implementation. This 2.0 version of Facelets should be very familiar to anyone who has been using Facelets 1.x. Most of the 1.x APIs are present, though there has been some tweaking/repackaging as part of the standardization process.

The inclusion of Facelets as a standard view declaration language should ease any concerns that development teams may have about embracing this technology.

While Facelets is a new focus for the JSF specification, JSP support is still available for those users who are not ready to make the jump to a new view definition technology. Note, however, that the JSP side of the JSF specification is basically standing still. None of the new features that involve new tags (composite components, system events, Ajax, etc…) are exposed through JSP.

Links

Composite Components

Let’s take a quick look at how to implement a custom component in JSF 1.x: Just implement your UIComponent subclass, and… done! Oh,wait… you might want to move your markup rendering code into a Renderer. Oh, and don’t forget to register your component and renderer in a faces-config.xml file. Er… then you just need to implement your JSP tag. Oh, and don’t forget that tld!

Okay, so JSF custom component development has always been a chore. The problems have long been known and are well documented.

JSF 2 greatly simplifies custom component development with the introduction of the “composite component” feature. This feature allows a custom component to be implemented with a single file – no Java code required.

Let’s take a look at the obligatory “Hello, World!” example, starting with a composite component that renders the salutation:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">
<head>
<title>My First Composite Component</title>
</head>
<body>

<composite:interface>
    <composite:attribute name="who"/>
</composite:interface>

<composite:implementation>
    <h:outputText value="Hello, #{cc.attrs.who}!"/>
</composite:implementation>

</body>
</html>

The composite component is defined via an XML file containing XHTML contents plus elements from the “http://java.sun.com/jsf/composite&#8221; namespace. The <composite:interface> element contains metadata that describes the characteristics of component, such as supported attributes, facets and attach points for event listeners. The <composite:implementation> element contains the markup that is substituted for the composite component when it is referenced by a consuming page.

To make the composite component available for use, we simply drop this file into a “resources” directory (more on resource loading later). The tag name for the composite component is derived from the file name. The tag namespace is based on the location of the composite component within the resources directory.

If we dump the above code in a “Hello.xhtml” file inside of a “resources/greet” directory, we end up with the following:

We can then reference our new component as follows:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:greet="http://java.sun.com/jsf/composite/greet">

  <!-- Snip -->

  <greet:hello who="World"/>

</html>

That’s quite a simplification from earlier days of writing UIComponent subclasses, renderers, tags, faces-config.xml entries and tlds!

The composite component architecture is much more sophisticated than demonstrated with this minimal sample. Support for all of the usual component-centric functionality is provided, including inserting facets, adding children, attaching listeners, validators, converters, etc… See the links below for more extensive coverage of JSF 2 composite components.

Links

Ajax

Here we are, 2009, four years since the term Ajax was coined. Hasn’t the JSF/Ajax integration problem been solved yet?

Well, actually, yes, it has. If the JSF AJAX Component Library Feature Matrix is any indication, this problem has been solved many times!

The availability of so many JSF/Ajax frameworks is a good indication that JSF provides a strong foundation for Ajax. So, does that mean that we are done? What’s left for the JSF spec to do?

Well, two things actually:

  1. Compatibility. While it is impressive that so many JSF/Ajax solutions are available, the subtle differences between these solutions lead to cross-framework compatibility problems.
  2. Native Support. Isn’t it time that JSF users have access to Ajax functionality without requiring a 3rd party framework?

JSF 2 attempts to address both of these issues by providing various new Ajax-related APIs and infrastructure. Let’s take a look at these by walking through the lifecycle of a typical Ajax request.

Ajax Request Lifecycle

Starting on the client, JSF 2 exposes a new JavaScript API, jsf.ajax.request(), that issues an Ajax request back to the current view. This method collects any data that needs to be included with the request, prepares the request payload, registers a response handling callback and then posts the request back into the Faces lifecycle.

Once the request enters the Faces lifecycle, the state of the Ajax request is captured via the PartialViewContext. This object provides access to information such as which components are targeted for processing/rendering. The PartialViewContext’s processPartial() method uses this information to perform partial subtree processing/rendering.

When the rendered response is sent back to the client, the callback previously provided by jsf.ajax.request() is invoked. This callback automatically updates the client-side DOM to reflect the newly rendered markup.

In order to encourage compatibility across JSF components/frameworks, the request and response payloads have also been standardized.

<f:ajax>

The jsf.ajax.request() JavaScript API is a primitive that is primarily targeted for use by frameworks as well as by the JSF implementation itself. JSF 2 also includes a declarative approach that is intended to be more convenient for page authors. This approach leverages the new <f:ajax> tag.

Instead of manually coding the JavaScript for the Ajax request call:

  <h:commandButton onclick="jsf.ajax.request(this,event,{render:'foo'});return false;"/>

Page authors can declaratively specify the same behavior:

  <h:commandButton">
    <f:ajax render="foo"/>
  </h:commandButton>

The presence of the <f:ajax> tag enhances the markup of the associated component to include a script that triggers the Ajax request. This allows Ajax requests to be issued without requiring the page author to write any JavaScript code.

Links

State Saving

JSF state saving has long been a sore point, both for application developers as well as component developers. The main problem for application developers is that the size of the saved state can be large. This makes client-side state saving impractical and leads to session state bloat. For component developers, the issue is that implementing saveState and restoreState methods is tedious and error prone.

JSF 2.0 addresses these issues with the introduction of a new “partial” state saving mechanism. This solution was inspired by a proposal that Adam Winer made (and implemented in Apache Trinidad) over 3 years ago. The key concept is that saving the entire state of the component tree is redundant, since the component tree can always be restored to its initial state by re-executing the view (ie. by re-executing Facelet handlers to re-create the component tree).

If we use the view definition to restore the component tree to its initial state, then the only state that needs to be saved is state that has been modified since the view was initially created. And since in most cases the number of components that are modified after component tree creation is small, the size of this delta state is typically much smaller than the full component tree state.

A requirement for the delta/partial state saving approach is that component implementations must know when their initial state has been fully configured. JSF 2 introduces the PartialStateHolder contract to help with this requirement. The PartialStateHolder’s markInitialState() method is called to notify the implementing component that its intial state has been established. Only modifications that occur after this notification need to be saved.

A second API has been introduced to help component implementations manage their state: StateHelper. The StateHelper provides storage for component state (such as attributes, listeners, etc…) and relieves the component author from having to provide custom saveState and restoreState implementations.

As a result of these new APIs, JSF 2 state saving is both more efficient and easier to use!

If the PartialStateHolder/StateHelper APIs seem vaguely familiar to you, you just might be thinking of Apache Trinidad’s FacesBean.

Links

System Events

JSF 1.x includes two event delivery mechanisms. FacesEvents are delivered to FacesListeners in response to user interaction, such as editing an input component, or activating a command component. PhaseEvents are delivered to PhaseListeners at the beginning and end of each phase in the Faces lifecycle. These solutions do not include notification of other interesting events that occur during the processing of a Faces request.

JSF 2′s system events provide the ability to deliver SystemEvents to SystemEventListeners at arbitrary points during the request processing lifecycle. System events fall into two categories: global system events and component system events.

Global system events are delivered in response to application-wide activities, for example Application initialization/destruction. Listeners for these events are registered via a call to Application.subscribeToEvent().

Component system events are specific to individual component instances. For example, a component system event is delivered each time a component has been added to the view, or rendered, or validated. Component system event listeners are typically registered via a call to UIComponent.subscribeToEvent(). However, component system events also bubble up to the Application, where they are re-delivered to Application-level listeners. This allows global monitoring of component-related events.

Both global and component system events are fired by calling Application.publishEvent().

In order to simplify listener registration for component-specific events, JSF also provides a declarative listener registration solution via the <f:event> tag. To register a listener declaratively, simply place the <f:event> tag inside of the target component. For example:

  <h:inputText>
    <f:event type="preValidate" listener="#{bean.doSomePreValidation}"/>
  </h:inputText>

This registers the method located at #{bean.doSomePreValidation} as a pre-validation listener for the parent inputText component.

By providing notification of all sorts of activities that previously went undetected, system events open up many possibilities for page authors, component authors, framework authors and also for the JSF implementation itself!

Links

Navigation

Implicit Navigation

In JSF 1.x, even the most trivial navigation cases required an entry in faces-config.xml. For example, when navigating from page1 to page2 in response to a “success” outcome on a command component in page1 required the following XML boilerplate code:

  <navigation-rule>
    <from-view-id>/page1.xhtml</from-view-id>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/page2.xhtml</to-view-id>
    </navigation-case>
  </navigation-rule>

Fun stuff, right?

JSF 2.0 introduces a simplification that reduces navigation-related grunge code: implicit navigation. If no matching navigation case is found after checking all available rules, the navigation handler checks to see whether the action outcome corresponds to a view id. If a view matching the action outcome is found, an implicit navigation to the matching view occurs.

The end result: smaller faces-config.xml files. Oh, and happier JSF users.

Conditional Navigation

Another enhancement to the navigation subsystem is the addition of conditional navigation cases. The conditional navigation feature allows navigation cases to specify a pre-condition that must be met in order for the navigation case to be accepted. The pre-condition is specified as an EL expression using the new <if> configuration element:

    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/page2.xhtml</to-view-id>

      <!-- Only accept this case if the following condition is true -->
      <if>#{foo.someCondition}</if>

    </navigation-case>

One of the motivations behind this feature is to allow pre-conditions to be implemented in a loosely coupled, navigation-agnostic way. Instead of requiring a managed bean or business layer object return a navigation-centric outcome value, we can now use EL to interact with arbitrary properties/methods on these objects, freeing these objects from awareness of the JSF navigation system.

Preemptive Navigation

The JSF 1.x navigation system is a black box. The only entry point, NavigationHandler.handleNavigation(), simply evaluates the navigation rules and causes a navigation to occur, without giving any insight into how the navigation target is determined.

JSF 2.0 provides more transparent view of the navigation system. The new ConfigurableNavigationHandler API provides access to metadata describing the available navigation rules/cases. In particular, the getNavigationCase method allows clients to ask the ConfigurableNavigationHandler to determine which navigation case matches a particular outcome and from action. With this new contract, it is possible to “preemptively” evaluate navigation rules and retrieve the resulting target view id and URL.

Why is this interesting? Well, before JSF 2.0, navigation rules were explicitly the domain of POST requests. Previously, the only time that navigation rules came into play was during the invoke application phase while handling a POST. By making the navigation rules available outside of invoke application, we open up the possibility of leveraging this information at other points in the lifecycle, for example, during render response.

As we’ll see in the next topic, this has some interesting consequences relating to better support for GET-based navigation and bookmarkability, an area that has received much interest in recent years.

Links

GET Support

It’s not so much that JSF 1.x does not provide any support for GET request handling… after all, there are some low-level primitives (like PhaseListeners) available. However, there is no denying that GET requests are a second-class citizen in earlier versions of the JSF specification. JSF 2.0 introduces several features that tackle this shortcoming.

View Parameters

The JSF 1.x specification goes to great lengths to provide a robust lifecycle for processing of values arriving from the client via Http requests. Values are pulled from the request, converted from strings to the proper target type, validated against application-specified constraints and finally, pushed into the model. Very powerful.

Of course, there is one caveat: all of this processing only applies to values arriving on POST requests. If the same value arrives via a GET request, well… tough luck! Or, well, maybe write a PhaseListener to manually process the request. Oh, and good luck reusing your converter/validator implementations to process those values!

JSF 2 brings some sanity to this situation with the introduction of “view parameters”, inspired by Seam’s page parameters. View parameters provide a simple, declarative way to map incoming request parameter values to any EL-reachable location. These mappings are specified using the new <f:viewParam> component, which lives in the (also new) <f:metadata> section of the view, eg:

  <f:metadata>
    <f:viewParam name="foo" value="#{bean.foo}"/>
  </f:metadata>

The above sample specifies that the value of the request parameter with the name “foo” will automatically be picked off of the request and pushed into the property at #{bean.foo}. So if we receive a GET request as follows:

page1.jspx?foo=bar

The value #{bean.foo} property will be set to “bar” when JSF starts processing the request. No more need to manually code this sort of mapping in a PhaseListener. Yay!

But wait, there is more… The <f:viewParam> component happens to be an EditableValueHolder, which means that view parameters can participate in conversion/validation. You can attach any converter/validator to an <f:viewParam> component , just as you would with, say, <f:inputText>. No more need to write custom conversion/validation logic specifically for GET processing.

PreRenderView Event

View parameters bring to GET requests much of the JSF request processing lifecycle that was formerly reserved for POSTs: request parameter decoding, type conversion, validation and model updates. But view parameters stop short of one last important step: invoking application-defined listeners. For this, system events come to the rescue.

JSF 2 includes a PreRenderViewEvent that is fired after view parameters have finished processing, but before the view is rendered. The pre-render view listener can be registered using the <f:event> tag, eg:

  <f:metadata>
    <f:viewParam name="foo" value="#{bean.foo}"/>
    <f:event type="preRenderView" listener="#{bean.doSomething}"/>
  </f:metadata>

This listener might be used to load data or set up context that is required prior to rendering. In addition, the listener may choose to programmatically navigate away from the requested view in the event that some pre-condition is not met (eg. the user does not have access to the requested page).

With the addition of view parameters and the pre-render view event, the GET request processing lifecycle is finally on par with the rich lifecycle provided for POSTs.

<h:link>/<h:button>

Now that we have the ability to respond to GET requests more effectively, what about the flip side? How do we issue these GET requests in the first place? Looking at the JSF 1.x components, <h:commandButton> and <h:commandLink> do not fit the bill as these components are form/POST-centric. <h:outputLink> works, but has the drawback that it requires manual construction of the destination URL.

JSF 2 includes two new components that simplify GET-centric navigation: <h:link> and <h:button>. With these components, the page author no longer needs to hand code the destination URL. These components leverage the JSF navigation system to determine the appropriate destination. Instead of explicitly specifying the URL, users specify the desired logical outcome, eg:

  <h:link outcome="success"/>

Preemptive navigation is used to translate this logical outcome into a physical destination. At render time, the navigation system is consulted to map the outcome to a target view id, which is then transparently converted into the destination URL. This frees the page author from having to worry about manual URL construction.

Note that the URL construction process is not solely based on the target view id. The <h:link> and <h:button> components also integrate nicely with view parameters. By specifying the includeViewParams attribute, eg:

  <h:link outcome="success" includeViewParams="true">

The view parameters specified by the destination view are taken into account when building up the URL – ie. an inverse mapping of the view parameters is applied. Each view parameter value is extracted from the location specified by its EL expression, converted to a string, and added to the query string under the view parameter’s name.

This provides a simple yet powerful mechanism inserting required parameters into the query string. It also provides a nice technique for transferring request-scope data across requests.

In addition, page authors may manually insert query parameters using the <f:param> tag, eg:

  <h:link outcome="success">
    <f:param name="foo" value="bar"/>
  </h:link>

And of course, the key benefit of this solution: the resulting URLs are bookmarkable!

Links

Scopes

View Scope

View scope is one of two new scopes introduced in JSF 2 that fall into the category of “longer than request, shorter than session” scopes. As the name implies, state that is placed into view scope is preserved until the user finishes interaction with the current view. If you have ever had the joy of trying to figure out why your command component isn’t firing after binding the rendered attribute to a request-scoped managed bean, view scope may just be the answer to your problems.

View scope state can be accessed programmatically via UIViewRoot.getViewMap(). EL access is available via the #{viewScope} implicit object.

Flash Scope

JSF 2 borrows a concept from Rails with the introduction of the new flash scope. Flash scope provides a short-lived conversation. State that is placed into flash scope is propagated across a single view transition, including surviving redirects, and is cleaned up before moving on to yet another view. If you have been resorting to session scope to store state that needs to survive a redirect, flash scope might just be for you.

Flash scope state can be accessed programmatically via the ExternalContext.getFlash() API. EL access is available via the #{flash} implicit object.

Custom Scopes

JSF 2 also provides a small enhancement to the managed bean system to allow faces-config.xml authors to place managed beans into custom scopes. The trick is that custom scopes are specified via an EL expression rather than a keyword, eg:

  <managed-bean>
    <managed-bean-name>foo</managed-bean-name>
    <managed-bean-class>com.foo.Foo</managed-bean-class>
    <managed-bean-scope>#{someCustomScope}</managed-bean-scope>
  </managed-bean>

The EL expression identifies the location of a map that holds the properties for the scope. When it is time to instantiate a custom-scoped managed bean, the managed bean system automatically pushes the new instance into the map under the specified name.

Links

Configuration

Managed Bean Annotations

JSF 2 provides a long awaited usability improvement with the introduction of annotation-based configuration. The goal of these annotations is to reduce the size and complexity of faces-config.xml files, which have a tendency to get quickly out of hand. The first set of annotations allows developers to configure managed beans. The old style XML configuration:

  <managed-bean>
    <managed-bean-name>foo</managed-bean-name>
    <managed-bean-class>com.foo.Foo</managed-bean-class>
    <managed-bean-scope>session</managed-bean>
  </managed-bean>

Can now be replaced with annotations on the bean class:

@ManagedBean
@SessionScoped
public class Foo {
}

The name for the managed bean is automatically derived from the name of the annotated class. In the above example, the presence of @ManagedBean annotation on the Foo class makes a managed bean with the name “foo” available. Alternatively, the @ManagedBean annotation also allows a name to be specified explicitly.

Annotations are also available for the other scopes, as well as for managed properties.

Note: An effort is underway to unify these bean/scope annotations across specifications (eg. JSF, JCDI) for Java EE 6. In the meantime, the JSF 2 managed bean annotations are considered an optional part of the JSF 2 specification. Mojarra and MyFaces already provide implementations of these optional annotations.

Component Annotations

As part of the effort to prune down XML configuration bloat, JSF 2 also includes annotations targeted at authors of custom components (and associated objects). These annotations include:

  • @FacesComponent
  • @FacesRenderer
  • @FacesConverter
  • @FacesValidator
  • @FacesBehavior

Of course, the good old faces-config.xml elements are still present for those who prefer to go that route.

Faces-config.xml Ordering

A long-standing problem with faces-config.xml loading is that the order in which these files are loaded is unspecified. For the most part (eg. for managed bean or navigation configuration) the order is not significant. However, there are certain cases, such as decorating Application-level objects (eg. ViewHandlers), where the order may matter.

During the JSF 1.2 timeframe, both MyFaces and the JSF RI adopted a convention whereby faces-config.xml files are loaded based on an order derived from the containing jar file’s name. However, this was just a temporary implementation-level solution that was put in place until the issue could be addressed by the specification.

JSF 2 solves this problem by allowing faces-config.xml files to provide ordering-related hints. Each faces-config.xml file may now declare a name (via a new <name> element) that can be referenced by other faces-config.xml files for ordering purposes. A new <ordering> element and sub-elements allow relative ordering requirements to be specified.

This addition to the spec provides a much cleaner/safer way for the various frameworks/component sets to play together in the JSF ecosystem. No more jar file name hacking!

Project Stage

Project stage is a new configuration option that allows the application developer/deployer to specify a hint to the JSF implementation regarding the role of the current deployment. Valid values include:

  • Development
  • Production
  • SystemTest
  • UnitTest

This hint allows the JSF implementation to optimize its behavior for the current stage. For example, the JSF implementation might provide more verbose development-time diagnostics than would be practical for a production environment.

For a more specific example, check out the Mojarra team’s recent use of project stage to provide automatic compression of JSF’s own JavaScript library.

The project stage can be set either as a context parameter (“javax.faces.PROJECT_STAGE”) or via JNDI (“java:comp/env/jsf/ProjectStage”).

And, yes, my good friend and colleague Matthias Wessendorf would also like to see the project stage exposed as a system property. :-)

Links

Behaviors

The original JSF 1.0 specification introduced the concept of “attached objects” – ie. objects that are not UIComponents, but are attached to UIComponents in order to influence some aspect of the component’s behavior. This technique is used for conversion and validation by value holding components, eg:

  <h:inputText value="#{foo.value}">
    <f:convertNumber integerOnly="true"/>
  </h:inputText>

JSF 2 adds a new class of attached object: the ClientBehavior. Whereas converters/validators focus on value processing, client behaviors assist in enhancing a component’s client-side functionality. Before client behaviors, page authors were forced to resort to hand-coding scripts and manually wiring these scripts up via event handling attributes, eg:

  <h:commandLink onclick="return confirm('Really???')"/>

Client behaviors allow such scripts to be packaged up into reusable bundles that can be attached to components declaratively, eg:

  <h:commandLink>
    <foo:confirm message="Really???"/>
  </h:commandLink>

This declarative approach is made possible by the introduction of two new contracts (along with various supporting APIs). The ClientBehavior contract specifies how client behavior implementations provide access to scripts and more generally how these objects participate in the component lifecycle. The ClientBehaviorHolder contract specifies how client behaviors are attached to components, similar to how EditableValueHolder specifies how converters and validators are attached.

In addition to defining these new contracts, JSF 2 also includes one concrete ClientBehavior implementation: the AjaxBehavior. The declarative form of this client behavior should be familiar from our earlier discussion on Ajax:

  <h:commandLink>
    <f:ajax/>
  </h:commandLink>

Although the JSF specification only defines a single concrete client behavior, the client behavior architecture is designed for extensibility. Expect to see plenty of third party client behavior implementations popping up!

Links

Validation

Bean Validation

The Bean Validation JSR (JSR-303) defines a generic, tier-independent mechanism for specifying data validation constraints. The specification includes several standard constraint annotations (eg. @NotNull, @Size, @Min, @Max, etc…) and also allows custom constraints to be defined.

JSF 2 provides built-in integration with JSR-303 constraints. In environments where a bean validation implementation is present, JSF automatically validates constraints for beans that are referenced by UIInput values.

In addition, <f:validateBean> may be used to fine tune bean validation behavior. For example, the validationGroups attribute may be used to manually specify which validation groups should be taken into account when validating a particular component:

  <h:inputText value="#{bean.foo}">
    <f:validateBean validationGroups="com.foo.validation.groups.Billable"/>
  </h:inputText>

When validation constraints fail, any associated error messages are automatically translated into FacesMessages by the JSF implementation, thus communicating the failures to the end user without placing any burden on the application developer.

Empty Field Validation

In previous JSF releases, Validators were not applied to EditableValueHolder components with null/empty submitted values. Unfortunately, this behavior limits the utility of constraints that actually check null/empty values, such as the JSR 303 @NotNull constraint. In order to support @NotNull and other similar constraints, JSF 2 changes the behavior of null/empty value validation. As of JSF 2, when a JSR-303 implementation is present, null/empty values are validated.

Since this may cause problems for legacy Validator implementations that do not expect to see null/empty values, the javax.faces.VALIDATE_EMPTY_FIELDS context parameter can be used to disable this behavior.

New Validators

In addition to <f:validateBean>, JSF 2 includes two other new validators:

  1. <f:validateRequired> provides required field validation.
  2. <f:validateRegexp> provides regular expression-based validation

Links

Error Handling

JSF users who are new to Facelets will appreciate the more informative Facelets error page that provides information such as: line numbers! (And no, not just stack trace line numbers, but actual line numbers within the Facelets file.)

Of course, error pages are only useful in cases where the triggering exceptions are allowed to propagate up to the error handling layer and not pre-maturely consumed. The JSF 2 specification helps in this area with the introduction of the new ExceptionHandler API. JSF implementations are now required to allow all “unexpected” exceptions to propagate out of the current lifecycle phase so that they can be handled globally by an ExceptionHandler instance.

This change should reduce/eliminate those mysterious, hard to debug “swallowed” exceptions, as the ExceptionHandler now acts as a central clearing house for exceptions. Another advantage of this centralization is that it allows users/frameworks to devise more sophisticated error handling strategies.

Resource Loading

If you spend time implementing custom JSF components of any complexity, eventually you are going to run into the question: what do I do with my component’s images (or JavaScript libraries, or style sheets)? Just about every JSF component framework has run into this problem and, in the absence of a standard solution, has solved this problem in its own proprietary way.

JSF 2 provides a standard solution to this problem with the introduction of the ResourceHandler API. The ResourceHandler is responsible for serving up resources (images, JavaScript files, style sheets, etc…) from well-known locations on the class path. Resource requests are routed through the FacesServlet, which passes these request onto the ResourceHandler for processing. This solution allows components and their resource dependencies to be bundled in the same jar file with no need for a bonus servlet, servlet filter or phase listener to serve up these artifacts.

JSF 2 also provides several new features in order to facilitate insertion of resource references. Authors of custom Java components can annotate their UIComponent subclasses with the @ResourceDependency annotation to identify any resources that need to be pulled in when the component is used. Composite component authors can use the new <h:outputScript> and <h:outputStylesheet> to pull in scripts and style sheets. The #{resource} implicit object provides direct EL access to resource URLs.

The @ResourceDependency annotation and the <h:outputScript>/<h:outputStylesheet> components take advantage of another new feature: resource relocation. Resource relocation gives the component/page author control over where resource references are inserted into the rendered markup. For example, resource references may be inserted into the document head or at the end of the body. In addition to providing flexibility in where resources are inserted, a beneficial side effect of resource relocation is that duplicate resource references are automatically pruned out.

Note that in order to support resource relocation, JSF 2 introduces two other new components: <h:head> and <h:body> These components render the HTML head/body markup and also provide a target for relocatable resources.

Links

Tree Visiting

JSF 1.2 included the most useful addition of the UIComponent.invokeOnComponent() API. This provided the ability to invoke a callback on a single component instance in context. This functionality is particularly handy for any case where a single component (or subtree) needs to be targeted. (Think Ajax.)

While invokeOnComponent() is an excellent solution for the single component case, it is not particularly optimized for the multiple component case. If you need to target two components (eg. need to render two separate subtrees while processing an Ajax request), invokeOnComponent() will work, but requires two tree traversals in order to locate the two components. What happens if you need to render five separate subtrees? Or, even worse, what if you want to visit every component in context? Unfortunately invokeOnComponent() is not the answer.

JSF 2.0 solves the multi-component visiting case by introducing a sibling API to invokeOnComponent(): UIComponent.visitTree(). Both of these APIs traverse the component tree and invoke a callback on a subset of components. While invokeOnComponent() is designed to visit a single component, visitTree() may visit multiple components – and possibly all components – during its traversal. The set of components to visit is specified via a VisitContext that is passed into the visitTree() call.

While tree visiting is currently used under the covers by JSF implementations for features such as Ajax and state saving, the hope is that JSF frameworks/users will find other use cases where this new API proves helpful. If you currently have any case where you are calling invokeOnComponent() repeatedly (or are calling findComponent() when you should be calling invokeOnComponent()), be sure to check out the new tree visitor API!

Links

Conclusion

When I starting thinking about writing this article, I was hoping to provide a comprehensive overview of the entire JSF 2 feature set. As I got further into this undertaking, I realized that covering every single new feature/API in a single blog entry might be a bit, well… unwieldy. As such I decided to trim back my plans, but just slightly. There are a small number of minor API additions that I have not discussed here. Perhaps I’ll add a new section on these minor APIs at some point. For the moment, I am hoping that the information provided here is sufficiently complete to meet my original goal of providing a good introduction to the JSF 2 feature set.

If I have missed some feature/API that you think deserves discussion here, please leave a comment. Or if you know of other good sources of information, please leave a link. I am planning to update this blog from time to time with links to new blogs/articles as they become available, perhaps even to some that I write myself. :-)

Still Here

January 5, 2009

Just wanted to post a quick note to let you all know that this blog isn’t dead yet! For the folks who have posted comments/questions on library partitioning: thank you for your interest – and sorry that I have not been able to respond just yet. I will be following up soon.

To anyone who happens to stumble by here, thanks for dropping in and happy new year!

Back From AjaxWorld

October 28, 2008

In spite of the fact that both Roger and I arrived at AjaxWorld carrying our east coast colds, we managed to make it through our “JSF and Ajax” presentation. Couple of snapshots from the presentation:

Andy and Jeremy Geelan

Roger and Andy

Two other EG members presented on JSF-related topics. Ted Goddard (ICEsoft) presented on ICEfaces’s support for Ajax Push on the iPhone. Ted’s presentation included a fun live demo where iPhone-enabled audience members were able to get into an ICEfaces-based chat room and push messages to each other. Jeremy Grelle (SpringSource) presented on Spring’s Ajax support, including coverage of Spring Faces and an interesting demo of “progressive enhancement”.

One other notable JSF-related presentation: Wesley Hales (JBoss/Red Hat) provided a great introduction to the state of affairs in the portal/portlet world. Wesley discussed how both ICEfaces and RichFaces approach portlet integration, and also covered how emerging standards will make life easier for Ajax/portlet development.

Other JSF old-timers (and old friends) John Fallows and Jonas Jacobi also presented, though not on JSF. John and Jonas focused on HTML 5, in particular on the WebSocket API and how Kaazing’s offerings make it possible to take advantage of HTML 5 features today.

With several EG members actually in the same place at the same time (an unusual occurrence), we took advantage of the opportunity to hold an informal face-to-face meeting. Roger, Ted, Jeremy, John, special guest attendee Blake Sullivan (Oracle) and I met to discuss declarative solutions for Ajax, an area that we are trying to shape up for the JSF 2.0 release.

Off To AjaxWorld

October 19, 2008

I am heading out to California this week to attend AjaxWorld West in San Jose.  In addition to having the opportunity to check out all sorts of interesting sessions, I will also be presenting with Roger Kitain from Sun MicroSystems.  Our presentation is JSF and Ajax: Past, Present and Future.  As you might imagine, we’ll be taking a look at how Ajax-based solutions have evolved in the JSF world and what we expect to come next in JSF 2.0.

Of course, any trip to the Bay Area wouldn’t be complete without my usual visit to Oracle HQ.  Once AjaxWorld wraps up I’ll be spending the remainder of the week at HQ, catching up with friends and teammates both old and new.

I am looking forward to a great week in California!

JavaScript Library Partitioning Runtime

October 18, 2008

In Hello, Library Partitioning! we took our first peek at the new ADF Faces JavaScript Library Partitioning feature.  In order to support this functionality, ADF Faces introduces two new configuration files.  In this entry, we’ll see how the metadata defined by these configuration files is used to optimize the JavaScript footprint of ADF Faces.

ADF Faces loads the library partitioning configuration files at application initialization time, starting with the “feature” configuration file.  Since the goal is to allow custom component authors to leverage the library partitioning system for their own JavaScript code, we use a tried and true technique for locating all available feature configuration files: ClassLoader.getResources().  Given a path to a resource file, ClassLoader.getResources() scans all jars on the class path and returns references to any matching files that are found.  This mechanism should be familiar to JSF users: it is the same approach used to locate faces-config.xml files.

In order to locate feature configuration files, ADF Faces searches for all “adf-js-features.xml” files in the “META-INF” directory.  This allows custom component authors that want to participate in JavaScript library partitioning to simply drop a “META-INF/adf-js-features.xml” file into their jar.  No explicit registration is necessary.  Any feature configuration files found are loaded into memory and merged into a common data structure.  Of course, ADF Faces provides its own feature configuration file so that its own features are always available.

In the case of the “partition” configuration, we only have one configuration file per application.  ADF Faces looks for this file, named “adf-js-partitions.xml”, in the “WEB-INF” directory of the web application.  If no such file is found, ADF Faces falls back to a default partition configuration that it provides.  The default partitioning is meant to provide reasonable behavior for most applications, though application developers are welcome to optimize as needed for their application.

Now that we’ve got all of this information available, how is it actually put to use?

During the render traversal, ADF Faces collects information about which JavaScript features are required by the page.  At the end of the traversal, the complete set of JavaScript features required by the (rendered) page contents is known.  Once we know the set of required JavaScript features, we use our partition configuration to map this to the set of required partitions.  And given the set of required partitions, we simply render HTML <script> references to these partitions, just before the end of the HTML document.

That’s it!  By using this technique, we end up pulling in just those “chunks” of JavaScript code that are needed by the page, thus reducing the total amount of code that needs to be downloaded/loaded.

Hello, JavaScript Library Partitioning!

October 14, 2008

In Almost Getting To The Point, we took a look at requirements for a solution to the JavaScript size vs # of round trips dilemma.  In this entry, we’ll see how those requirements translate into an actual solution as implemented by the ADF Faces “JavaScript library partitioning” feature.  In this solution, we have three types of JavaScript artifacts:

1. The JavaScript “class”

This is a coherent set of code contained in a single file, which typically implements the equivalent of a class.  For example, the “oracle/adf/view/js/component/rich/layout/AdfRichPanelStretchLayout.js” file contains the JavaScript code for the af:panelStretchLayout’s JavaScript component class.

In our solution the class is the smallest unit of content that can be aggregated.

2. The JavaScript “feature”

Since component authors do not want application developers to have hard dependencies on JavaScript file names or paths, we introduce the concept of the JavaScript “feature”.  The JavaScript feature is a collection of JavaScript files that are associated with a logical identifier that describes the feature.

For example, the af:panelStretchLayout component implementation is contained within two JavaScript files:

* oracle/adf/view/js/component/rich/layout/AdfRichPanelStretchLayout.js
* oracle/adfinternal/view/js/laf/dhtml/rich/AdfDhtmlPanelStretchLayoutPeer.js

These two files are grouped into the “AdfRichPanelStretchLayout” feature.  This allows application developers to refer to the af:panelStretchLayout code by the name “AdfRichPanelStretchLayout”, without having to worry about the number, name or locations of files that are used to implement this feature.

3. The JavaScript “partition”

JavaScript “features” are usually small units of JavaScript code – typically a few related files that combine to implement a single area of functionality (such as a user interface component).  JavaScript “partitions” group JavaScript features into larger collections with the goal of influencing download size/number of round trips

For example, it’s not uncommon for applications that use the af:panelStretchLayout component to also use the af:panelSplitter component.  These two components often go hand in hand.  Assuming we have both an “AdfRichPanelStretchLayout” feature and an “AdfRichPanelSplitter” feature, these two features would be a good candidate to be placed in the same JavaScript library partition.

Looking at the division of responsibilities, we have:

  • Component authors place their JavaScript code in files.
  • Component authors are responsible for grouping these files into logical “features”.
  • Application developers are responsible for further grouping these features into larger “partitions”.

In order to support these responsibilities, the ADF Faces JavaScript library partition solution introduces two new configuration files: the JavaScript feature configuration file and the JavaScript partition configuration file.  Let’s take a look at each of these.

The feature configuration file is an XML-based file that groups JavaScript files into features.  A (slightly simplified) sample feature definition for our AdfRichPanelStretchLayout feature:

<?xml version="1.0" encoding="utf-8"?>

<features xmlns="http://xmlns.oracle.com/adf/faces/feature">

  <!-- Define the contents of the AdfRichPanelStretchLayout feature -->
  <feature>
    <feature-name>AdfRichPanelStretchLayout</feature-name>
    <!-- This feature contains two classes - the component and the peer -->
    <feature-class>oracle/adf/view/js/component/rich/layout/AdfRichPanelStretchLayout.js</feature-name>
    <feature-class>oracle/adfinternal/view/js/laf/dhtml/rich/AdfDhtmlPanelStretchLayoutPeer.js</feature-name>
  </feature>

  <!-- Other feature definitions go here -->

</features>

Pretty simple really.
The partition configuration is similar, but groups features into partitions:

<?xml version="1.0" encoding="utf-8"?>
<partitions xmlns="http://xmlns.oracle.com/adf/faces/partition">

  <!-- Define the contents of the "stretch" partition -->
<partition>
<partition-name>stretch</partition-name>
    <feature>AdfRichPanelStretchLayout</feature>
    <feature>AdfRichPanelSplitter</feature>
  </partition>

  <!-- Other partition definitions go here -->
</partitions>

ADF Faces provides a feature configuration file for its own set of components/framework features and also provides a default partition configuration so that application developers are not required to define a partitioning themselves.

So, now that we’ve got all of this wonderful information about our JavaScript code base, what do we do with it?  That’s the topic of the next entry of course. :-)

Almost Getting To The Point

October 14, 2008

In Does Size Matter? we concluded that, while aggregating JavaScript code is generally a good thing, at a certain point we might need to back off and consider breaking up our code.  At the moment ADF Faces is at one end of the size vs. round trip spectrum.  The number of round trips is optimized by combining all JavaScript code into a single library (single round-trip).  At the other end of the spectrum, we could optimize total downloaded code size by breaking out each JavaScript “class” into its own library (many round trips).  Clearly some happy medium – a balance between size and round trips – is needed.

Perhaps the ideal solution would be a GWT-like approach.  We could consider analyzing JavaScript code usage to determine the bare minimum code requirements down to the method level.  While this would certainly lead to a highly optimized solution, it does have one drawback.  This is hard!  In a traditional JEE/JSP/JSF application, JavaScript code lives in a number of places, some of which are not exactly easy to identify.  JavaScript code may be bundled up into jar files or war files (not too hard to identify), or may live inside of JSPs or other templates (slightly harder to identify), or may be generated programmatically via Java code (very hard to identify).  That’s not to say that this approach is impossible or not worthwhile; this is clearly an idea that is worth pursuing.  However, given the scope of such a project, a solution along these lines was simply not in the cards for our current release.

So, if we aren’t able to perform code analysis to produce a minimal application-specific JavaScript library, what are our other options?  Let’s start by considering some requirements that we would like our solution to meet.

1.  Aggregation.  We want a solution that allows us to group JavaScript files into larger “chunks”.  At the moment, the ADF Faces JavaScript code is delivered in one big chunk.  We want to break this up into smaller chunks that can be delivered to the browser independently.

2.  Specificity.  Any given chunk should only be downloaded/loaded on pages that need the chunk.  So, for example, if the JavaScript code for the af:richTextEditor  component lives in its own chunk, this code should only be pulled in on pages which use the af:richTextEditor component.

3. Cacheability.  Chunks should be cacheable.  That is, the contents of the chunks should not vary from page to page.  If a chunk is required by both page A and page B, it should not be necessary to download the chunk a second time when navigating from page A to page B.

4. Tunability.  The number and content of the chunks should be configurable at the application level.  Different applications have different JavaScript usage patterns and should be able to optimize the chunks (ie. optimize the size vs. round-trip trade-off) accordingly.

5. Abstraction.  When defining the contents of a chunk, the application developer should not be required to reference the physical JavaScript file names or locations.  For example, when defining a chunk that includes the JavaScript code for the af:richTextEditor component, the application developer should not need to know that the af:richTextEditor implementation relies on code located in the “oracle/adfinternal/view/js/laf/dhtml/rich/AdfDhtmlRichTextEditorPeer.js” file.  File names and locations are implementation details that are easily changed/re-factored.  Instead of relying on file names, the application developer should reference the code via some logical identifier that is guaranteed not to change.  This protects both the component author (freedom to change/re-factor) and the application developer (freedom from breaking when pesky component authors make changes).

6. Defaults.  Some default set of chunks should be provided so that application developers are not forced to go to the trouble of defining their own chunk layout.

7. Ordering.  The solution should ensure that chunks are loaded in an order that honors code dependencies between chunks.  If chunk A depends on code in chunk B, chunk A should be loaded before chunk B.

8. Extensibility.  Custom components should be able to participate in the solution.  That is, it should be possible to chunk custom component code in the same manner as ADF Faces framework/component code.

Assuming we’ve hit the key requirements (and hopefully we did, as I am running out of serious-sounding words to describe each requirement), these requirements translate into a fairly straightforward solution.  Which of course is the topic of my next entry. :-)


Follow

Get every new post delivered to your Inbox.