 |
Community: Java Enterprise Archives
Most detailed JSF 2.0 reader: Manfred Riem
Posted by edburns on June 20, 2008 at 10:01 AM | Permalink
| Comments (0)
At JavaOne 2006, Dennis
Byrne shared with me an intimate fact that I'll now share with you:
his Christmas 2005 wishlist included "a bound printout of the JSF 1.2
spec". He got his wish and went on to become a star committer to the
MyFaces project. Dennis certainly gets the "most touching reading of
the JSF spec" award. However, the award for "most detailed reading of
the JSF spec" clearly goes to Manfred Riem, creator of the Manor 'n Rock JSF
Components . Mr. Riem read the spec with a fine toothed comb and
filed 50 issues in the issue tracker! Thanks Manfred. I
owe it to you to fix every one.
JSF Usage and JSF 2.0 Update
Posted by edburns on November 06, 2007 at 08:35 AM | Permalink
| Comments (3)
Graphical Indicators of JSF Usage
From time to time, the JSF team at Sun surfs around a bit looking for
new Internet sites using JSF. This time, my colleague Roger Kitain discovered
that Virgin
Megastore is a JSF User.
Within Sun, we have an elevator
pitch-like slide deck about JSF, and the most important slide
therein is at the left. If you want more details about the sites
pictured, or you want to add some more sites to the list using JSF, the
wiki page is <http://wiki.java.net/bin/view/Projects/RealWorldJSFLinks>.
By way of update on JSF 2.0, Jacob Hookom, the developer of Facelets
and JSF Expert Group member, is leading the drive toward our number one
goal
for JSF 2.0: Making custom components easier to develop. We're
expecting an EG-private proposal from Jacob this week. Once we get it
firmed up we'll share it publically in an Early Draft Review of the
spec. In other JSF 2.0 news, we have provisionally closed on the issue
of resource loading, as listed in [115-CompResources].
This will also be in the EDR.
Technorati Tags: edburns
Swiss JSF User Group Formed
Posted by edburns on August 01, 2007 at 10:56 AM | Permalink
| Comments (0)
Because I was presenting MCP at
the first ever Jazoon conference, my
friend and expert JSF Developer Alexander Jesse invited me to speak at
the first ever JSF User Group meeting. The meeting was held at a Credit
Suisse office in Zürich on the evening of the last day of the
Jazoon conference.
Credit Suisse is the largest financial institution to go public with
its investment in JSF, though I have it on good authority that Deutsche
Bank, and Oesterreichische Kontrollbank also have made significant
investments in JSF. Mr. Jesse's presentation
at Jazoon detailed how Credit Suisse has achieved significant advances
in developer productivity, UI uniformity, and maintainability by
creating a custom JSF component library specific to the needs of Credit
Suisse IT developers. Mr. Jesse printed up flyers announcing the JSF
user group meeting and these were distributed in the Sun and Credit
Suisse booths in the exhibitor area, as well as at every one of the five
JSF related presentations at Jazoon.
The primary goals of this inaugural meeting was to decide if there
was a need for a JSF user group in Switzerland, should the group be a
special interest group (SIG) within JUGs or a standalone group, and how often should the
group meet. Secondarily, Mr. Jesse and I would present some fun
technical content, not found anywhere else at Jazoon.
The slides from the meeting can be found here:
We had about 22 people attending the meeting, about half of whom had
heard of it from the conference. The response was enthusiastic. Alexander's notes from the meeting can be found at his blog, at <http://ajesse.wordpress.com/2007/07/12/jsf-usergroup-ch-meeting-1/>.
Please leave a comment on this blog if you're interested in the next
meeting.
Technorati Tags: edburns
Vacation: Backwards Compatibility Story
Posted by edburns on July 25, 2007 at 03:40 PM | Permalink
| Comments (1)
Back in college I spent many hours
of my copious Freshman year free time playing LHX on Will Day's PC. At the
time, all I had was an Apple //c, which was already behind the times by
then. As you can read in the Wikipedia entry, this was a flight
simulation game. The thing I remember most was the "missle-cam" view,
where you could fire a TOW missle and then switch to the missle's eye
view, where you controlled the missle until it hit the target. Well,
during my recent vacation, I decided to see if I could find a way to
play it on a current computer. Sure enough, the thing still runs
unmodified. No emulator or anything.
As we're starting up JSF 2.0 I'll keep this
runtime backwards compatibility firmly in mind as I corral debate and
discussion on new features.
Technorati Tags: edburns
Testing Ajax Apps with JUnit
Posted by edburns on May 04, 2007 at 01:47 PM | Permalink
| Comments (0)
JavaOne is practically here, so I thought I'd give a preview of one
of the sessions I'm on next week. This one is close to my heart, BOF
6825 Testing Web 2.0 Features, Using Real-World Applications. I'll
be talking about using The Mozilla
Control Program (MCP) to write an automated test that exercise an
Ajax application. Big deal, right? Well, yes because MCP enables you
to make assertions about the actual Ajax transactions, and also allows
you to access the browser DOM using the plain old W3C DOM API in
Java.
To make this easy, I've recorded an Elluminate screencast showing MCP
in action testing the Dynamic Faces and jMaki sample
application. If you're a Sun employee and you choose not to view
this screencast just because I'm making you use JavaWebStart to view it,
please tell me so I can report you to the "eating our own dogfood"
police.
To view the screencast, click here.
Compilllers are Helpful
Posted by edburns on March 12, 2007 at 09:11 AM | Permalink
| Comments (2)
When working to revive Webclient
as a means to enable one to write automated tests for Ajax Applications,
I ended up fixing some thread safety assertions that were failing in
native code. Part of this involved slightly recrafting the design of
the native/Java DOM bridge, originally written over seven years ago by
Igor Kushnirsky. Igor's
original design had lots of public native methods. My
problem was that I needed these methods to have their native code
executed on a particular thread. However, the DOM methods can be called
from any old thread in the application. Webclient already does this
with an internal NativeEventThread class. All webclient
methods that end up in native code happen on that thread. Basically, I
had to go through the Java DOM code and turn this:
public native Element getElementById(String elementId);
into this:
public Element getElementById(String elementId) {
// Make this happen on the NativeEventThread.
return nativeGetElementById(elementId);
}
native Element nativeGetElementById(String elementId);
Of course, I would have to modify the function names in the native
C++ source files as well.
In case you were wondering, I did consider these solutions but
rejected them.
- Use Javier Pedemonte's Java XPCOM bridge
- I plan to completely rewrite the mozilla layer of webclient and dom
to use this most excellent software after I get the 2.0 release done. I
don't have time for that extensive rewrite now.
- Use aspect oriented programming techniques
- Sure, I could do this, but I don't want to introduce another
dependency on another technology.
That said, I wrote some xemacs macros as I went along and it only
took a couple hours of manual editing. While doing it, I re-compiled
all along the way. Naturally, the compiler caught some things, which I
easily fixed, as I went along.
This got me thinking. Say this code was written entirely in a
scripting language. If so, this sort of "complicated, human-assisted
global search and replace" change (I won't call it refactoring since
this particular process was so specific to JNI) would be really error
prone and hard to debug. The absence of a type checking compiler would
really make this sort of change hard.
I assert that this sort of change is happens all the time in the
maintenance phase of a large software project. I assert that the person
making the change is seldom the same person who wrote the code
originally. Given these assertions, I predict much woe for the
maintenance programmer who has to do such a change on a scripting
language based project. I continue to urge caution for those listening
to scripting zealots when they consider moving more of their projects to
scripting languages.
Technorati Tags: edburns
##jsf irc channel usage
Posted by edburns on January 19, 2007 at 12:03 PM | Permalink
| Comments (0)
Because JavaServer Faces technology is delivered by Sun as a part of
the Java EE SDK and also Project Glassfish, the Sun JSF
team strongly feels that community is important. To that end, I've been
plugging the use of the ##jsf irc channel on irc.freenode.net as a
community resource. My team and I try to maintain a daily presence in
the channel. Since
we started hanging out there, we've seen the daily traffic steadily
grow.
Now that over a year has passed, I thought it would be fun to throw
in a graph. Here is a chart of the daily log size for the ##jsf
channel, where each data point is a weekly average of the size, in
bytes, of the daily log file. The first datapoint in the x axis is from
the fourth week of 2006, on up to today.
If you want to join the channel, please see the
instructions at the JSF main site.

Many thanks to Geert Bevin who,
very graciously and professionally provides the log bot on the
channel.
Technorati Tags: edburns
Adding Dynamic Faces Support to a jMaki widget
Posted by edburns on December 07, 2006 at 09:09 AM | Permalink
| Comments (1)
In this entry, I show how I added Dynamic Faces support to the Dojo
Inline Editor widget in jMaki.
Background and History
If you've read my blog before, you know that I think JSF is a good
fit for handling the motherhood
and apple pie requirements of web applications. What you may not
know is that jMaki intentionally
leaves the work of satisfying these requirements as an exercise for the
developer. No problem, just use jMaki and JSF together. This is indeed
a valid answer, but there is a subtlety that bears clarification.
When using jMaki + JSF under J2EE 1.4 (the default target audience
for jMaki), you miss out on the following features:
Ability to have the jMaki widget POST back to the faces
page while preserving the JSF view state.
Ability to use jMaki widgets that represent components
that accept user input within an iterating component such as
dataTable.
Ability to attach valueChangeListeners to jMaki
components in the view.
Ability to attach converters and validators to jMaki
components in the view.
Ability to attach action and/or actionListeners to
jMaki components in the view.
These deficiencies stem both from missing features in the built-in
jMaki JSF support and from missing features in JSF 1.1 commonly used
with J2EE 1.4.
The story about jMaki and Dynamic Faces
By using jMaki with Dynamic Faces on top of
JavaEE 5, however, all of these deficiencies can be addressed (with the
exception of the last two, and issues have been
filed
for these features). This section discusses how using jMaki and Dynamic
Faces addresses all of the deficiencies mentioned above.
- Ability to have the jMaki widget POST back to the faces page while
preserving the JSF view state.
-
This is the big one, and it was at the heart of the JavaOne
presentation in which I participated. The lack of this feature in
many Ajax + JSF solutions is what prompted us to title the session,
"Ajax done right". When you do not have the JSF view state, you
cannot do any of the things that JSF does well. Including
the JSF View state in the Ajax transaction is essential.
By using Dynamic Faces to send and receive Ajax transactions from
the browser to the JSF view, the JSF view state is correctly
preserved, allowing the entire JSF lifecycle to be used, including
conversion, validation, events, etc.
- Ability to use jMaki widgets that represent components
that accept user input within an iterating component such as
dataTable.
-
This one is near and dear to Jacob Hookom's heart.
Not only do you need the JSF view state, but you need a way to apply
individual values to an individual components within a composite
component (such as a table or tree). This capability did not exist in
JSF until version 1.2, and Dynamic Faces takes full advantage of it.
- Ability to attach valueChangeListeners to jMaki
components in the view.
This didn't exist in jMaki until issue 3
was fixed. However, even though you can add a valueChangeListener to a
jMaki component now, you still need to preserve the JSF view state in
order for it to ever have a chance of being invoked. Again, Dynamic
Faces is the answer.
Ability to attach converters and validators to jMaki
components in the view.
Ability to attach action and/or actionListeners to
g jMaki components in the view.
As with valueChangeListener, these two need to be first
implemented in jMaki, then they need to be used with Dynamic Faces.
How To
The whole point of jMaki is to put today's hot JavaScript widget
libraries in the hands of Java web application developers. Each widget
library has different ways of doing things, and indeed, each widget
within each library does too. jMaki solves this by having specific
files with each widget. Therefore, adding Dynamic Faces support to each
widget involves making some modifications to the widget specific files.
Currently, the only widgets that have been modified are the Dojo FishEye and Inline Editor, and the Scriptaculous Inplace Editor. This section shows some high
level guidelines for how to add Dynamic Faces support to an arbitrary
jMaki widget.
The widget specific files for a jMaki widget are:
| File Name
|
Purpose
|
| component.css
|
Any CSS style associated with an instance of this widget.
|
| component.htm
|
The markup that will be included in the page an instance of this
widget.
|
| component.js
|
The JavaScript adapter file for this widget. This adapts between
the widget library specific way of doing things and the jMaki server
side framework. This is also the easiest place where Dynamic Faces
support can be added.
|
| widget.json
|
Any name/value pairs that aid in the configuration of an instance of
this widget.
|
In general, you'll probably just need to modify component.js to add
Dynamic Faces support. Please follow Jennifer's Tutorial for how to get
started with jMaki and Dynamic Faces. Once you've done that, you need
to make sure to include the Dynamic Faces taglib and script tag in the
page on which you are using the jMaki widgets.
Syntax highlighting courtesy of http://www.nopaste.com/.
Listing 1, the JSP Page
<%@ taglib prefix="a" uri="http://java.sun.com/jmaki-jsf" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces"%> <h2>Editor Using JSF </h2> <f:view> <jsfExt:scripts /> <h:form prependId="false"> <h:dataTable id="table" rows="10" binding="#{ResultSetBean.data}" value="#{ResultSetBean.list}" var="customer"> <h:column> <f:facet name="header"> <h:outputText value="Account Id"/> </f:facet> <h:outputText id="accountId" value="#{customer.accountId}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Customer Name"/> </f:facet> <a:ajax name="dojo.inlineedit" value="#{customer.name}" /> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Symbol"/> </f:facet> <h:outputText id="symbol" value="#{customer.symbol}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Total Sales"/> </f:facet> <h:outputText id="totalSales" value="#{customer.totalSales}"/> </h:column> </h:dataTable> </h:form> </f:view>
Line 4 has the taglib for Dynamic Faces, line 11 uses the scripts
tag. Line 29 has the use of the jMaki ajax component.
Let's take a look at the component.js for the Dojo Inline Edit
widget, before Dynamic Faces support was added.
Listing 2, the component.js before Dynamic Faces is added
dojo.require("dojo.widget.*"); dojo.require("dojo.widget.InlineEditBox"); dojo.require("dojo.event.*"); var container = document.getElementById(widget.uuid); var w = dojo.widget.createWidget(container); w.getValue = function() { return w.textValue; } // add a saveState function if (typeof widget.valueCallback != 'undefined') { w.onSave = function(newValue, oldValue) { // we need to be able to adjust this var url = widget.valueCallback; dojo.io.bind({ url: url + "?cmd=update", method: "post", content: { "value" : newValue }, load: function (type,data,evt) { // do something if there is an error } }); } } w.saveState = w.onSave; jmaki.attributes.put(widget.uuid, w);
On lines 1 - 3 we have the dojo includes: uninteresting. Line 5 of
listing 2 is interesting. The "widget" refererred to is this instance
of this widget in the page. In this case, it's the widget on line 29 of
Listing 1. However, keep in mind that line 29 of listing 1 is inside of
a dataTable, therefore, there will be 10 instances of this widget in the
page, each corresponding to an actual JavaScript object in the
JavaScript VM. Therefore, the value of widget.uuid will be
different for each widget, and will, most importantly, correspond to the
JSF Client Id for the widget in the JSF view. This is important because
in order to address the widget in the JSF view, you need its client
id.
For example, the widget.uuid values for this page happen
to be table:n:j_id_id34 where n is the
numbers 0 to 9.
Returning to line 5 of listing 2, the actual DOM element returned by
the call to document.getElementById is what jMaki renders
based on the content of the component.htm file. For the
dojo inline editor, this file is:
<div id="${uuid}" dojoType="inlineEditBox" class="dInlineEdit">${value} </div>
The jMaki AjaxWrapperRenderer will cause the
component.htm file to be rendered like this in the page
from listing 1.
<div id="table:0:j_id_id34" dojoType="inlineEditBox" class="dInlineEdit">name_0 </div>
Therefore, when line 5 of listing 2 executes, the value of
container is the div element with id
table:n:j_id_id34, where n, of course, is the
current row in the table.
Line 6 of listing 2 uses the dojo createWidget to create
an instance of the inline edit box inside of the container
element.
Lines 14 - 25 of listing 2 declares the JavaScript function that will
be called when the user presses the "save" button in the widget UI.
Now, let's take a look at the changes to component.js necessary to
add Dynamic Faces support, expressed as a diff.
Listing 3, the diffs to component.js to add Dynamic Faces support
--- component-pre-DF.js 2006-12-07 10:32:25.000000000 -0500 +++ component.js 2006-12-07 10:31:19.000000000 -0500 @@ -12,6 +12,16 @@ // add a saveState function if (typeof widget.valueCallback != 'undefined') { w.onSave = function(newValue, oldValue) { + + if (typeof _globalScope.DynaFaces != 'undefined') { + DynaFaces.fireAjaxTransaction(container, + { + execute: widget.uuid, + render: "none", + postBody: widget.uuid + "=" + newValue + }); + } + else { // we need to be able to adjust this var url = widget.valueCallback; dojo.io.bind({ @@ -22,7 +32,8 @@ // do something if there is an error } }); + } } } w.saveState = w.onSave; -jmaki.attributes.put(widget.uuid, w); \ No newline at end of file +jmaki.attributes.put(widget.uuid, w);
The only change is a conditional within the onSave
function. jMaki defines a _globalScope global variable
that allows you to access all things globally defined in the page. It
so happens that the scripts included by virtue of line 11 of listing 1
define a global variable called DynaFaces. This JavaScript
object has all the functions exposed by the Dynamic Faces JavaScript
library. Therefore, you can safely test for the existing of Dynamic
Faces in a page as shown on line 8 of listing 3. If Dynamic faces is
not being used in the page, then the normal jMaki operation of the
widget takes place, as shown on lines 17 - 23 of the diff.
Lines 9 - 14 of listing 3 cause a Dynamic Faces Ajax transaction to
be made back to the JSF page currently being viewed in the browser.
This transaction includes all the view state for the current
f:view. The first argument to
fireAjaxTransaction is the DOM element from which the
transaction should be fired. It is important that this be the DOM
element that corresponds to the actual JSF UIComponent in
the view. The second argument to fireAjaxTransaction is a
JavaScript associative array. In this case, we're saying three things:
do the 'execute' portion of the JSF lifecycle just on
the JSF UIComponent for this widget instance.
do not re-render anything to the browser (in this case,
Dojo handles it).
In the HTTP POST body of the request, include the name
value pair for the currently entered value of the widget.
Note that newValue, on line 6 of listing 3, is an
argument to the onSave function. It is the new value
entered by the user.
For more information on the JavaScript functions exposed from Dynamic
Faces, see the
Dynamic Faces Reference.
Summary
jMaki gives you cool widgets. Dynamic Faces + jMaki gives you cool
widgets you can use in a real enterprise web application.
Technorati Tags: edburns
(near) Zero (re-)Deployment Time for JSF
Posted by edburns on December 01, 2006 at 06:52 PM | Permalink
| Comments (4)
One oft cited complaint about Java Web Applications is the slow
and laborious deployment
step. This step seriously undermines the ability to get into a
flow
state and is generally a major buzz kill. The absense of a
deployment step is one reason why people like Ruby on Rails so
much.
JSF-Extensions Design Time brings good news for
flow-impaired Java Web application Developers: the JMX
PhaseListener.
The implementation of this was really simple. I just took Jean-Francios
Arcand's JMXDeploy class, modded it ever so slightly, as you
can see in the
source code, and called it from a
PhaseListener.
I did a screencast about it too.
Technorati Tags: edburns
Motherhood, Apple Pie and Web apps
Posted by edburns on November 13, 2006 at 08:35 AM | Permalink
| Comments (2)
In my recent spate of speaking
engagements, I have been including a "motherhood
and apple pie" slide in my presentations about JSF and Ajax. I put
this in my slides in response to a question I sometimes hear when I make
the case for JSF and Ajax. The question goes something like this:
Hey, why do I need JSF, or any other server side framework for that
matter? With Ajax, or things like GWT, can't I just put it all in the
client? I mean, let's just do everything in JavaScript!
You're welcome to do that, but if you do, please
know that you'll have to do all of these things yourself.
As you may guess, JSF already does all of these for you, does them quite
well, and does them in a way that is an industry standard, with the
brainpower of leading minds from Oracle, Sun, IBM, Apache, the Open
Source Community, and others.
This is why I have been spending my spare time trying to get Project jMaki to have first class
support for JSF as a core part of its feature set and value proposition.
In fact, if you support this idea, please send an email to the
jMaki User list saying that you think this is important. For some
exmples of this in action, please see here, here, here,
and here.
Ed Burns Upcoming Speaking Engagements
Posted by edburns on September 08, 2006 at 08:32 AM | Permalink
| Comments (0)
 |
I'm currently cooking up two presentations about Ajax and JSF. Once
they're fully baked, I'm taking them on the road! Of course, while on
the road I'll be promoting my first book, JavaServer Faces: The
Complete Reference. This book can be referenced from http://purl.oclc.org/NET/jsfbook/.
Here are the stops on my fall 2006 tour.
At each of these engagements I'll be presenting one or two of the
following two talks.
Enterprise Grade AJAX with JSF
This presentation will demonstrate how JSF and AJAX are perfect
together. We begin with an insight into the design heritage of JSF, and
how that heritage puts JSF in good stead to be productive in the AJAX
world. Building on that foundation we dive into the code from the page
author and component developer's perspective. We close with a look to
the future of JSF.
Scripting JSF
The benefits of scripting languages for web development are well
known. Python, Ruby, Perl, and other languages came to prominence
largely due to their suitability for web development. With the inclusion
of JSR 223 in the Java platform, Scripting will be fully supported. This
presentation will present some trends for using Scripting to develop
applications for Java EE.
|
I hope to meet lots of people and learn how you all are using JSF.
If you're not using JSF, maybe I can find out why so we can fix it.
|
|
|
|
Technorati Tags: edburns
Introducing Project Dynamic Faces
Posted by edburns on August 30, 2006 at 09:41 AM | Permalink
| Comments (6)
After a few months of steady improvements, we're ready to announce an
early access release of Project Dynamic Faces (DynaFaces). The project
homepage is <https://jsf-extensions.dev.java.net/>.
This page has live demos of DynaFaces in action.
This project is being developed in Open Source, using the OSI
approved CDDL license. Your contributions and bug reports are very
welcome!
Please visit the Slides
and Screencasts page for an introductory presentation, and a
screencast of that presentation, including demos.
I'm Lucy van Pelt this week.
Posted by edburns on August 15, 2006 at 09:11 AM | Permalink
| Comments (0)
This week, my colleague Roger
Kitain and I are sitting in the virtual advice
booth, however, instead of doling out psychiatric
help we're answering JSF questions.
Please stop by at http://java.sun.com/developer/community/askxprt/
and ask some questions.
My community support time that I normally spend on the
JSF IRC channel is consumed with these questions this week, so you
probably won't see me on the channel this week. However, other weeks
please visit the channel and you can chat with me directly.
Technorati Tags: edburns
JSF on Maven: refresh
Posted by edburns on July 18, 2006 at 12:33 PM | Permalink
| Comments (1)
With the help of Kohsuke Kawaguchi's
most excellent maven repository
importer ant task, and several iterations of trial and error, we now
have the JSF 1.2 and 1.1 api and impl jars available under the same license as
Glassfish on the
java.net maven repository.
Put this in your project.properties or build.properties:
maven.repo.remote=https://maven-repository.dev.java.net/nonav/repository/,http://www.ibiblio.org/maven/
groupId: javax.faces
artifactId: jsf-api
artifactId: jsf-impl
available versions: 1.1_02, 1.1_03-SNAPSHOT, 1.2, 1.2_01_B04, 1.2_01-SNAPSHOT
I have also updated the POMs. If you're a JSF developer with
committer access, please update the pom file in the source tree if you
want to be more officially recognized.
Technorati Tags: edburns
JSR 252 Gantt Chart Video
Posted by edburns on June 16, 2006 at 09:17 AM | Permalink
| Comments (2)
See the video here.
JavaOne Video: AJAX DONE RIGHT
Posted by edburns on May 31, 2006 at 11:15 AM | Permalink
| Comments (7)
If you really want, you can skip the prose and go straight to the
video.
However, if you do, you'll miss out on where to download the
demos.
This was an interesting JavaOne for me because I was in a funny
position with respect to my talk. I had submitted a proposal for a
JavaOne talk when the call for papers went around. JSF EG members Jacob Hookom and Adam Winer submitted a similar
talk, unbeknownst to me. The JavaOne paper review team suggested we
collaborate on a talk, and, since we were already collaborating
informally on ideas, it was no problem to collaborate on a talk. But
speaking of collaboration...
With AJAX being hot and new and all, everyone wants to get a piece of
the pie, do something cool, and get famous. (I'm certainly no
exception). With all of these chefs in the kitchen, approaches to AJAX
are bound to overlap and in come cases conflict. I had been working
with the Sun Blueprints team on their AJAX
components, and some of the ideas we developed in those components
have been picked up and extended by Shale
Remoting. Meantime, Greg Murray had been
working on his jMaki project.
Then there's Jonas
Jacobi and John Fallows and their weblets thing they have in their
book. There is also ICESoft's icefaces and
Exadel's ajax4jsf. Finally,
there are a lot of ideas bobbing around on the myfaces dev list, some of
them from my co-speakers Adam and Jacob. Clearly, there is a need for
some community refactoring.
Now, here's the funny part. The approach to AJAX and JSF that Adam
and Jacob have been advocating, and that I advocate as well, is
different, yet potentially complimentary, to what Greg was doing with
jMaki. It also does not align perfectly well with some of the things in
Shale Remoting. It fits pretty well with ajax4jsf and I'm not sure
really how it relates to icefaces. Now, come JavaOne, here I am
standing on stage with Jacob and Adam, and the developers of all the
AJAX technologies listed above (and probably more) were in the audience,
and our talk was titled, "AJAX Done Right". As if to say, "everyone
else is doing it wrong". I wasn't too comfortable with such a
confrontational title, but, hey, this is the age of the technology smackdown and all that
jazz, so I went along with it.
People tend to take critique of their creations personally, so I want
to set the record straight and say that each approach has value and none
of them have all the answers for all situations for doing AJAX. That's
a good thing because we can harvest all these great ideas in the
upcoming JSF 2.0 spec. In the meantime, Jacob and I are putting forward
our take on JSF and AJAX in the JavaServer™ Faces
Technology Extensions. Project. For more on the future of that
project, I'll have an upcoming blog.
Now without further ado, here is the complete video of our talk AJAX
DONE RIGHT in Flash Live Video format. Thanks to Dennis
Byrne for shooting the video on Adam's camera.
The demo shown in this talk, as well as the demo shown at the Sun Web
Tier Pod on the JavaOne 2006 show floor, are available for download here.
You'll need to or Glassfish to run them.
Technorati Tags: edburns
New release of JSF AJAX Components (Updated)
Posted by edburns on April 20, 2006 at 06:51 AM | Permalink
| Comments (14)
Many thanks to my pal Vernon Singleton for handholding me through the process of converting these huge QuickTime files down to much smaller FLV and SWF files. Maybe he'll do a blog on how to do it!
Nearly a year ago, the BluePrints and JSF teams at Sun began to work
on the story of how AJAX and JSF would work together. As we began to
get into it, we found that these two technologies were very
complimentary. We developed and continue to refine techniques for how
to use AJAX with JSF.
The landing page for the Java BluePrints AJAX components is:
<https://blueprints.dev.java.net/ajaxcomponents.html>
I've recorded a screencast blog for each of the components in the
catalog. Please excuse my slow pace of speaking, I'm aware that we have
a large contingent of European JSF developers and my tendency is to
speak fast American English. Therefore, I made a conscious effort to
speak slowly.
These components leverage the Dojo
Toolkit and make use of the JSF PhaseListener approach
for serving up JavaScript files and handling AJAX requests on the JSF
server. This approach was innovated by the Blueprints and JSF teams and
generalized in the Shale
Remoting library, which these components leverage to great
effect.
Technorati Tags: edburns
Survey: JSF Implementations in App Servers and Developer Tools
Posted by edburns on March 27, 2006 at 10:22 AM | Permalink
| Comments (1)
Updated: app servers added to query
Rather than spend lots of time researching this, I thought I'd try my hand at asking a question of the blogosphere.
I'd like to know what developer tools and application servers are using which JSF implementation. I know that WebSphere Studio (or RAD, or whatever it's called these days) used Sun's JSF impl pretty much off-the-shelf, and that Oracle uses Sun's with major Oracle extensions in its JDeveloper product. What about other application servers, tools and IDEs? Does any tool use MyFaces?
Thanks,
Ed (JSF co-spec-lead)
Technorati Tags: edburns
Using JSP Immediate Expressions to access JSF Data
Posted by edburns on March 15, 2006 at 10:48 AM | Permalink
| Comments (7)
Here is an ultra-quick blog entry sharing something in JSF 1.2 about
which I'm not sure many people are aware. Thanks to the unified EL, it
is possible to refer to JSF managed beans and other JSF concepts using
plain old JSP expressions in the page. For example, let's say you have
a JSF app that is a bookstore. In the app is a managed bean that is a
Map where the keys are ISBN numbers and the values are Book JavaBeans
that have properties like author, title, ISBN, etc.
In JSF 1.1, to display any information from the book Map, you had to
use JSF components. In JSF 1.2, you can use plain old JSP ${}
expressions to access this data, like this:
The title is ${books["0072262400"].title}.
Even though books is a managed bean, you can still
access it without JSF.
Keep in mind that you can also access all the implicit objects,
including JSF ones, in this manner. For example, if you wanted to use
EL to get the locale of the current view, you could say:
${view.locale}
As a final example, if you wanted to get the remote user name of the
current user using standard Servlet authentication APIs you could
say:
${facesContext.externalContext.remoteUser}
Basically anything that conforms to JavaBeans naming conventions and
is accessible from the FacesContext or
UIViewRoot can be reached via the EL in this way.
Technorati Tags: edburns
Repost: Using JAAS with JSF
Posted by edburns on March 07, 2006 at 01:33 PM | Permalink
| Comments (13)
The content and ideas in this blog entry are taken from my upcoming
McGraw Hill Osborne book JavaServer Faces: The Complete
Reference, which I am co-authoring with Chris Schalk. In the
book, we have a chapter on Securing JavaServer Faces applications. This
excerpt shows how the extensible design of JavaServer Faces can be used
to allow JAAS to provide authentication to a JSF Web application. JAAS
Authorization with JSF is also covered in the book, but not in this
excerpt.
|
We will conclude this chapter by showing how to enhance the example
application by leveraging the standard security infrastructure of the
Java platform. From its inception, the Java platform has treated
security as a first class concern. Indeed, one of the first benefits of
Java was to securely bring dynamic behavior to web deployed
applications. Over the years, the implementation and API to security
has evolved, but the core principals have improved and become steadily
more secure. Therefore, choosing to build your application managed
security on top of the standard Java security features is a very safe
bet.
A term often applied to Java security is JAAS, which is short for
Java Authentication and Authorization Service. JAAS started out as an
optional package in JDK 1.3 but has become a core part of the Java
platform as of JDK 1.4. As the name implies, JAAS covers the first two
of the three main aspects of security: authentication and authorization.
Let's explore one way to integrate JAAS style authentication and
authorization into the application
Using JAAS Authentication in the example application
While it would certainly be possible to call into the JAAS layer
directly from the example application logic, for example, from the
UserRegistry bean, a more re-usable solution is to encapsulate the JAAS
interface in a custom ActionListener. This approach de-couples the
security completely from your application and takes advantage of the
intended use of the ActionListener extension hook.
The mechanics of providing such an ActionListener are described in
Chapter 11, but let's review briefly here. The first step is to modify
the faces-config.xml file for the example reusable component library so
that it includes the action-listener declaration, as shown here.
<application>
<action-listener>
com.jsfcompref.examplecomponents.util.JAASActionListener
</action-listener>
</application>
Then, leverage the decorator pattern, as described in Chapter 10, to
delegate most of the work to the "real" ActionListener by providing a
constructor that saves a reference to it. Following the constructor,
the processAction( ) method must be implemented, as described below.
private ActionListener parent = null;
public JAASActionListener(ActionListener parent) {
this.parent = parent;
}
public void processAction(ActionEvent event)
throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
UIOutput comp = null;
String userid = null, password = null;
JAASHelper jaasHelper = new JAASHelper();
// Check to see if they are on the login page.
boolean onLoginPage = (-1 != context.getViewRoot().getViewId().
lastIndexOf("login")) ? true : false;
if (onLoginPage) {
if (null != (comp = (UIOutput)
context.getViewRoot().findComponent("form:userid"))) {
userid = (String) comp.getValue();
}
if (null != (comp = (UIOutput)
context.getViewRoot().findComponent("form:password"))) {
password = (String) comp.getValue();
}
// If JAAS authentication failed
if (!jaasHelper.authenticate(userid, password)) {
context.getApplication().getNavigationHandler().
handleNavigation(context, null, "login");
return;
}
else {
// Subject must not be null, since authentication succeeded
assert(null != jaasHelper.getSubject());
// Put the authenticated subject in the session.
context.getExternalContext().getSessionMap().put(JAASSubject,
jaasHelper.getSubject());
}
}
parent.processAction(event);
}
The first thing to note is that part of the usage contract for
JAASActionListener is the requirement that the username and password
components be nested inside a UIForm named "form", and be named "userid"
and "password" respectively. This expedient measure allows the
JAASActionListener to easily extract the user-provided values for
username and password so that they can be passed on to the JAASHelper
class. The second thing to note about the usage contract is the
requirement that the application provide a navigation rule for the
outcome "login" that causes the user to be directed to the login page if
the authentication failed. In the failure case, processAction( ) is not
called until after redirecting to the "login" outcome using
NavigationHandler. If authentication succeeded, the Subject is stored
in the session for later access. The java.security.Subject is the Java
class that represents the user to the runtime. (We'll cover Subject in
greater detail in the section on JAAS authentication.) Finally, the
parent processAction( ) method is called to do the normal action
handling. Note that this causes the existing application managed
authentication, as described in Chapter 9, to take place. A production
quality implementation would probably remove the application managed
authentication in favor of using JAAS, rather than just supplementing
it, as we have done here.
Let's examine the JAASHelper class.
public class JAASHelper {
LoginContext loginContext = null;
public JAASHelper() {
}
public boolean authenticate(String userid, String password) {
boolean result = false;
try {
loginContext = new LoginContext("FileLogin",
new LoginCallback(userid, password));
loginContext.login();
result = true;
}
catch (LoginException e) {
// A production quality implementation would log this message
result = false;
}
return result;
}
public Subject getSubject () {
Subject result = null;
if (null != loginContext) {
result = loginContext.getSubject();
}
return result;
}
public static class LoginCallback implements CallbackHandler {
private String userName = null;
private String password = null;
public LoginCallback(String userName, String password) {
this.userName = userName;
this.password = password;
}
public void handle(Callback[] callbacks) {
for (int i = 0; i< callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback)callbacks[i];
nc.setName(userName);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback)callbacks[i];
pc.setPassword(password.toCharArray());
}
}
}
}
}
The authenticate( ) method uses the class
java.security.auth.login.LoginContext to perform the login. The login(
) method of this class will throw a LoginException if the login fails
for any reason. This exception is caught by authenticate( ) and it
responds by setting result to false. false. If no exception is thrown,
result is set to true. authenticate( ) ends by returning the value of
result.
The two arguments to the LoginContext constructor are the most
important part of this example. The first, the literal string
"FileLogin", refers to an implementation of the
javax.security.auth.spi.LoginModule interface. This interface is
implemented by a provider of a particular implementation of
authentication technology, for example JNDI, LDAP, or database. In this
example, we use a free software implementation called "tagish" that
provides a simple file based authentication scheme. The implementation
comes from John Gardner and can be found at http://free.tagish.net/jaas/.
Providing a LoginModule implementation is beyond the scope of this
chapter, but we must illustrate how to use one, once it has been
provided. This is the beauty of JAAS, the authentication technology
itself is separated from the rest of the system. In other words, if you
want to plug in LDAP, do it by providing a custom LoginModule.
The JVM is made aware of the existence of a LoginModule
implementation either through a -D flag, or via a modification to the
JAVA_HOME/jre/lib/java.security file. In our case, we use
the former option: -Djava.security.auth.login.config==
D:/Projects/example/chapterCode/ch14/example/src/resources/tagish.login
Note the use of forward slashes instead of the standard Windows
backslashes. Also note the "==" instead of just one "=". The format of
this file is prescribed by JAAS:
FileLogin
{
com.tagish.auth.FileLogin required
pwdFile="D:/Projects/example/chapterCode/ch14/example/src/resources/passwd";
};
The FileLogin identifier must match the argument to the LoginContext
constructor. The first element inside the FileLogin declaration is the
fully qualified class name of the class implementing LoginModule. In
our application, we have bundled tagish.jar, which contains this class,
into the WEB-INF/lib directory of the application. The required flag
tells the system that the login must succeed, and whether it succeeds or
fails, the login must still proceed down the LoginModule chain. Other
valid values for this flag are requisite, sufficient, and optional and
are described in the javadocs for the class
javax.security.auth.login.Configuration. The pwdFile argument is an
implementation specific parameter to the code in tagish.jar that tells
it where to find its password file. The format of this file is also
implementation specific and for the example app looks like this:
username:MD5 Hash Of Password:group*
The specific file for the example follows:
# Passwords for com.tagish.auth.FileLogin
jfitness:5a64edabc9358c603103053a3c600a88:user
stiger:40be4e59b9a2a2b5dffb918c0e86b3d7:user
guest:084e0343a0486ff05530df6c705c8bb4:user
jake:1200cf8ad328a60559cf5e7c5f46ee6d:user:manager
Obviously, a simple MD5 hash of the password is not at all secure and
a production quality implementation would use an actual encryption
algorithm. For the purposes of security, MD5 is just as secure as
Base64 encoding, described earlier in the chapter, which is to say, not
at all secure. A handy MD5 hash calculator can be found at
http://bfl.rctek.com/tools/?tool=hasher. Note that user jake is a
member of the user and manager groups, while all the other users are
simply members of the user group. Groups will come into play in the
next section.
The second argument to the LoginContext constructor is an
implementation of the javax.security.auth.callback.CallbackHandler
interface. The LoginCallback implementation saves the username and
password ultimately originating from the userid and password components
in its constructor and uses standard boilerplate code to propagate them
to the JAAS system.
|
Technorati Tags: edburns
Repost: Bringing Ruby on Rails's Flash to JSF
Posted by edburns on March 01, 2006 at 12:20 PM | Permalink
| Comments (5)
With the demise of the Sun Engineer's Sandbox, my content posted there has disappeared. Thankfully I saved a copy. Thanks to srcerer on the ##jsf chat room on freenode for reminding me to repost this.
Overview
To celebrate the release of Ruby on Rails (RoR) 1.0, I have taken the
flash
concept from Rails's ActionController and brought it to
JSF. For those unfamiliar with RoR or the flash, the flash is basically
a map whose entries have a finite, container enforced lifetime. The
concept is familiar; it's the same old "scope" concept used in the
"request", "session" and "application" classes in the Servlet spec. The
point of the flash is to hold information you discover on this
request, that you want to use on the next request, but want to be
forgotten after the next request is finished
Figure 1 is a cheesy graphical depiction of the request, flash,
dialog, session, and application scopes.

The nice thing about these scopes is that they all have a Map into
which you can stick things. These Maps have the special property that
they will be cleared when the scope ends. In the case of the flash, the
map is cleared after exactly two runs through the JSF request processing
lifecycle.
I included Shale's Dialog
concept for good measure since I believe this concept is important to
the future of JSF For example, it's so important that JBoss Seam also
provides a similar concept. A Shale dialog or Seam conversation is
a scope whose length is determined by the application developer.
Background
Of course, I needed a release-vehicle for this thing so I created a
new glassfish
sub-project on java.net called jsf-extensions. My
intent is to use this project for a number of extensions to the core jsf
implementation. The flash is just the first the first that is ready for
public use. Others in the works include:
A completion and implementation of Jacob Hookom's JSF
Avatar proposal
A generalization of the Sun JSF implementation's JSP
tag library generator. This tool is used in the Sun
implementation to generate the TLD and tag handlers for the
html_basic taglib from the existing standard JSF component
metadata in the standard-html-renderkit.xml file.
The idea is to generalize this tool so it can be used to
generate the taglib for any JSF component.
A generalization of the PhaseListener
approach used in the Sun
Blueprints Solutions Catalog AJAX components to serve up
JavaScript files so that it can serve up any file out of a
component jar. This problem is solved in MyFaces using the Extensions
Filter but a PhaseListener is a more self-container
approach. This problem is also solved by the Weblets Project
but personally I don't think the problem of loading resources
is big enough to warrant an entire top-level project. Also,
weblets has extra XML configuration steps that simply are not
necessary if you use the PhaseListener approach.
But enough about the future of jsf-extensions, let's
quickly examine how to use the flash by examining the sample war
included in the jsf-extensions download.
Getting Started
Download and unpack the jsf-extensions
download.
Download a recent build of glassfish, I used Build
31.
Start it up by going to the bin directory and
running:
./asadmin start-domain domain1
Then deploy the sample app by executing:
./asadmin deploy --user admin --password adminadmin ~/jsf-extensions-1.0alpha1/wars/run-time-test-0.1.war
Of course, you need to adjust your path to the war accordingly. The
app will then be accessible at http://localhost:8080/run-time-test-0.1/.
This will take you to an index page where you should click on the "Ruby
on Rails-style Flash" link.
App Traversal
This app illustrates using the Flash from JSP. It is also possible
to use the flash directly from Java Code, or via the EL API. These
latter two methods are described in the JavaDocs.
As you may know from Jennifer
and Pierre's article on the Unified EL, JSF expressions can be
accessed in a "get" context, or a "set context", otherwise known as
"rvalue" or "lvalue", respectively. Thefore, the EL Expression
#{flash.foo} will store a value into the hash under the key
"foo" when evaluated as an lvalue, while it will retrieve the value
under key "foo" from the flash when evaluated as an rvalue.
In JSP pages, most expressions act as rvalues, whereas the lvalue
behavior does not occurr until the form is submitted and the values
entered by the user are stored into the expressions. However, to make
it easier to set expression values from JSP, including setting into the
flash, the jsf-extensions library includes the jsfExt:set
tag. A simple usage of this tag found on the first page in the sample
app, flash.jsp, is shown below.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>RoR Flash Test Page 1</title>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions" %>
</head>
<body>
<f:view>
<h:form id="form1">
<h:panelGrid columns="2" border="1" width="600">
Store into the flash when rendering this page
<jsfExt:set var="#{flash.foo}" value="fooValue" />
Value of <code>\#{flash.foo}</code>, should be <code>null</code>.
<h:outputText value="#{flash.foo}" />
<h:commandButton value="reload" />
<h:commandButton value="next" action="next" />
</h:panelGrid>
</h:form>
</f:view>
</body>
</html>
|
We're using the panelGrid tag (in way we not possible before JSF 1.2,
due to the problems pointed out in Hans
Bergsten challenge) to lay out the contents in a simple two column
table. The first row shows the use of the jsfExt:set tag
to store a value into the flash. The second row shows how to get things
from the flash. When viewing this page the first time, you won't see
anything in the "Value of #{flash.foo} row" until you press the "reload"
button in the page. This is because the normal use-case of the flash is
to store things in this request that will be accessed on the next
request.
If you want to store something in the flash for use on this request,
click on the "next" button in the sample app for an example. In this
page we use the "flash.now" syntax, shown below in JSP.
<jsfExt:set var="#{flash.now.bar}" value="barValue" />
<h:outputText value="#{flash.now.bar}" />
|
By inserting the special keyword "now" we tell the flash that this
store operation should be accessible on this request, rather than the
next request. If, during processing, you decide you want to promote the
value from flash.now to the real flash, use "flash.next" as shown on the
next page of the sample app.
<f:verbatim>
<jsfExt:set var="\#{flash.now.buckaroo}" value="banzai" />
</f:verbatim>
Value of <code>\#{flash.now.buckaroo}</code>, should be
<code>banzai</code>.
<h:outputText value="#{flash.now.buckaroo}" />
Promote buckaroo to stick around for the next request.
<jsfExt:set var="#{flash.keep.buckaroo}" value="#{flash.now.buckaroo}" />
|
When you click on the next button, you will be shown a page that
shows that the value in the flash has indeed survived the postback.
Show that buckaroo is still here.
<h:outputText value="#{flash.buckaroo}" />
|
This is a brief introduction to using the flash, a more in-depth
article would cover a common real-world use-case, such as doing
master-detail, and also cover the other two entry points to using the
flash, the EL API, and direct programmatic use.
Technorati Tags: edburns
Java EE SDK Runs ADF Faces
Posted by edburns on February 27, 2006 at 08:15 AM | Permalink
| Comments (1)
The saga of Oracle ADF Faces on the Java EE SDK continues. In our
last installment, Adam
Winer explained why ADF Faces won't run on Glassfish. I'm happy to
report that after some minor tweaks to Sun's JSF implementation in the
Java EE SDK, I think I have it running. However, I would appreciate any
testing people could give to see if the entirety of ADF Faces works.
ADF Faces is a large piece of software and their demo app is rather
comprehensive. Incidentally, it's also a great testcase for extending
JSF and exposed a few bugs which have also been fixed.
Here's how to try it. I'm using the jsf-glasssfish-updater technique
described in an
earlier blog.
Download and
install the Java EE 5 SDK. If you already have JDK 5.0
installed, you can just download Sun Java System
Application Server PE 9 Beta. Currently there is no
Mac OS X build of the Java EE SDK, but don't despair! Mac
Users will have to use Glassfish,
the Open Source Application Server from which the Java EE SDK
is built. Mac OS X is my main development platform, so I know
it works there.
Go to the the
nightly download area. If you're running the Java EE SDK
Preview, download the
jsf-sjsas9pebeta-updater.jar. If you're running
Glassfish, download jsf-glassfish-updater.jar
Execute this with the JDK 5 Java interpreter.
java -jar jsf-<glassfish-or-sjsas9pebeta>-updater.jar <PATH_TO_YOUR_ASINSTALL_DIRECTORY>
Where <glassfish-or-sjsas9pebeta> sjsas9pebeta or
glassfish, and PATH_TO_YOUR_AS_INSTALL_DIRECTORY is the
parent of the lib, bin, domains
(and so on) directories.
Download Oracle ADF Faces from Oracle's
website. Note, you have to join their developer network
to get it.
Unfortunately, ADF Faces appears to have been developed
without taking advantage of the benefits of the robust SecurityManager in Java EE 5.
Therefore, you'll have to put the following entry in your
server.policy file if you want the
chooseDate component to work from the
adf-faces-demo.war.
grant codeBase "file:${com.sun.aas.installRoot}/domains/domain1/applications/j2ee-modules/adf-faces-demo/WEB-INF/lib/adf-faces-api-SNAPSHOT.jar" {
permission java.net.NetPermission "specifyStreamHandler";
};
Of course, you'll have to tweak the entries if you use the components
in your apps. Also of note, the Sun App Server team has been debating
turning the security manager off by default, so this step may not be
necessary in the future.
Make sure any attempts to deploy a previous version of
adf-faces-demo.war have been completely removed
from the App Server. For example, I have noticed that
occasionally the adf-faces-demo directory stick
around in
domains/domain1/applications/j2ee-modules. I had
to manually remove this directory to enable the demo to
work.
From the ADF Faces download, deploy the
adf-faces-demo.war to your running Java EE SDK
App Server and visit the demo to enjoy ADF Faces on Java EE 5!
If you find any bugs when trying the demo please file them on the JSF
issue tracker or the Glassfish
issue tracker.
Also, note that this version of JSF includes the new
invokeOnComponent feature we developed with help from Jacob
Hookom and mentioned in
his blog. Lastly, the jsf jars in the java.net
Maven 1 Repository have been updated as well.
Technorati Tags: edburns
New Drafts of Java EE Web Tier: JSF 1.2, JSP 2.1, Servlet 2.5
Posted by edburns on February 17, 2006 at 12:50 AM | Permalink
| Comments (7)
I'm pleased to announce another revision of the Java EE Web Tier. In
Jan Luehe's blog
you can find out what's new in JSP 2.1 Proposed Final Draft 2 (PFD2).
The Change
Log for Servlet 2.5 will give you the scoop on the Servlet spec.
This blog entry will show what's new in the JSF spec.
In JSF, the most visible new feature since the last draft of the spec
is the addition of the invokeOnComponent() method on
UIComponent. See below for more details.
This revision of the Java Web Tier is fully implemented in glassfish
build 37, Sun's open source Java EE 5 Application Server, and the
basis for the upcoming Java EE SDK.
Spec changes since PFD, chronologically by section number
9.5: The TLDDocs
for the h: and f: taglibs are now a normative part of the
spec.
5.4: Use of JSR-250 Common
Annotations @PostConstruct and
@PreDestroy for managed bean lifecycle
notifications. See my
August 2005 blog entry for more on this feature.
3.1.10: Specify how EL ValueExpressions
must me handled in the attributes map returned from
UIComponent.getAttributes().
5.4: List the supported Java EE 5 annotations one may
put in a JSF Managed bean.
@Resource
@Resources
@EJB
@EJBs
@WebServiceRef
@WebServiceRefs
@PersistenceContext
@PersistenceContexts
@PersistenceUnit
@PersistenceUnits
2.2.2: Define the term "local value" more concretely.
Preface: Added section on backwards compatibility with
previous versions of the JSF spec.
9.4.8: Explicitly state that the use and meaning of a
UIParameter child is the responsibility of the
parent component inside which it is nested.
5.3: State that managed bean properties may be Java
enum types. Define coercion rules.
7.1.1: Widen the expected type returned from a
UICommand action method to be Object
instead of String. This allows the use of Java
enum types as returns from action methods, which can simplify
navigation rules.
7.3: State that the Action method must return
Object.
3.1.8: New method:
UIComponent.invokeOnComponent(), and supporting
callback interface ContextCallback. This method
allows you to execute a callback on an arbitrary node in the
view given its clientId. An override is provided
for UIData that provides for correctly
positioning the table to the proper row before continuing to
find the component.
9.3.1.2: Add a note mentioning that
tld-version in an explicit taglib def, and
version in an implicit taglib def are
semantically equivalent with respect to their use in
determining the backwards compatability strategy employed.
JSF-API Contract Changes, chronological by |