I wanted to start a new section that pertains to detail criticism of the spec. rather than a discussion of JSF as a solution. I've read the spec. a few times and really dove into the sections and tried to figure out what I didn't like. Here's my thoughts, feel free to comment on these and add your own. I'm sending mine to the JSR group and I think everyone should do the same.
PS I didn't finish all my thoughts, but they are mostly complete.
Assuming that most applications will be setup like:
HTML->HTTP->FacesServlet->reconstitute phase->validation phase->model phase
This leads to an enormous amount of duplication as well as overhead. The information for each form component will be stored in the HttpServletRequest, expanded into the UIComponent Tree and stored in the FacesContext and finally migrated to the Application's Model. Although this seems to be a small amount of work when considering smaller forms with two or three fields, it could become larger with 20-30 field forms. This continues to grow when considering an intensive web application with many users (i.e. 20+ requests per minute). In addition, the cost of the UIComponent and Application's Model classes themselves might further increase the amount of memory consumed by this triple duplication as they may contain other member variables that increase each instances foot-print. In addition, without some comparison mechanism, the HttpSerlvetRequest parameters will be copied to the UIComponents local values, which will be copied to the Application's Model each request. If, for example, the request goes all the way to the Invoke Application phase and then encounters an error, which will redirect the user back to the form so that they can fix some values, after they have fixed the values and resubmitted, the triple transfer happens, in its entirety, again (unless the application program is exceptionally savvy and is willing to build in an update recognition component that could skip application model updates when they are not needed).
The simpler and more concise design seems to be a single duplication of data. This would be from the HttpServletRequest to the Application's Model. This would remove the UIComponent's local values entirely. The UIComponent tree could still be constructed and optimized however the JSF spec allows. Likewise, the UIComponent's themselves could be "backed" by the Application’s Model classes as is the case in the MVC design of Java’s Swing APIs.
The decoding process would work the same but would store the decoded information in the Application's Model. Likewise, the encoding would retrieve it from the Application’s Model. This mimics other frameworks such as Jakarta Struts with their ActionForm classes that are essentially the Application's Model (or at least positioned in such a way that they could be).
This needs to be rewritten. This contains information about the Lifecycle management process before the reader knows what that is.
I don't really like the concept of 1 Tree to 1 page yet, but I don't know why. Need to think about this and draw some concrete conclusions about how this is lacking and what impacts it will have.
How will applications be able to forward to HTML pages? It doesn’t seem possible in the current setup without creating Tree objects for pages that don’t contain JSF code. Likewise, it seems that the requirement of having response Trees dictate the outbound page require that every JSP page in the entire application use JSF code (in order to seem conceptually correct). This seems like a large requirement for businesses with existing info-structure. Not to mention the need to be redirected out of the J2EE application server to an ASP server. Of course no one wants that, but it is a reality. This seems very restricting. The flow should be flexible enough to support forwards and redirects to any resource inside and outside the container.
The requirement on forcing the Tree to be saved to the response or the session seems very restricting. This section is very ambiguous about what writing the Tree to the response means. Does this mean doing nothing because the JSF tags will do everything for you? Or does it mean adding additional information to the HTML about the state of the JSF system? In the latter case, this is simply duplication of the information that the JSF tags write out, is it not? And there might be implementations with large Trees and many users that do not want to bug down the session with this information and would rather spend the computing cycles to reconstruct it each time from the request. Additionally, would there be cases where a developer would want to send the information from a normal HTML page to the JSF system and have it construct a UIComponent Tree? This seems likely and not possible (?) with the requirement from this section.
If you decide to leave in the local values and model values that I disagreed with above, you'll need to be specific about where the values for the response come from when encode is called. It they come from the local values of the UIComponent, then the application logic will need to be responsible for migrating the values from the Application's Model to the UIComponent's local values. If they come from the Application’s Model, then every component will need to supply model references (I think). Or a better solution to this problem would be to add another phase to the lifecycle called "Update Local Values" which is designed to update the UIComponent's local values from the Application’s Model if necessary. Or you could simply do away with the UIComponent’s local values altogether in favor of a more MVC oriented system where the view is directly backed by the Application's Model (similar to Swing).
You probably want to add a way to determine a components individual and absolute id (bar and /foo/bar). This will be useful in tools as well as debugging.
This was a major concern to me when I wrote both of my frameworks. A reusable Validator is excellent because it reduces the amount of code duplication. However, it is very difficult to tailor messages for specific UIComponents using a reusable Vaildator. For example, on one page I just a text box for age and on another I use if for income. I don't want my error messages to be generic stating that, "This value must be greater than 0 and less than X". I want the user to know what must be within the range.
Another solution is requiring specific sub-classes for each message required, or some parameter from the page to denote the specific message to use. The former clutters up the packages with tons of Validators and also requires way too much coding. The latter completely negates the ability to use parameterized messages without further bogging down the page with all the (un-localized) parameters to the error message or forces the placing of all the parameters inside the resource bundle for the error messages with a standard naming scheme (i.e. for the first parameter to the message "longRange.montlyOverhead.0=Your monthly overhead"). Since 1/3 of any application is really the view and interaction of which a large chunk is error messages, this is a major issue that must be considered. Because it always happens that the CEO plays around with the application one day and says, "I really wish this error message read this"... and then you're in for some major headaches, unless this problem is solved up front.
JSF 3.5.2.x and 4.x and 7.6.x
These sections seem to break up the flow of reading. The previous sections were charging forward with information about the interfaces, the JSF classes and specifics about what is required for each Phase. Then we need to down shift quite a bit to talk about default/standard implementations that ship with JSF or are required to be implemented by implementers. I think that these should be contained in a later section after 5, 6, 7 and 8.
What are the implications of this decision on Internationalization? When different UIComponents encode using different Locales and the HttpServletResponse’s content type has already been set, there could be rendering problems on the client side in the browser.
Messages added to the message queue during validation or processing contain Unicode String Objects and could be written in any language. The Message Object does not contain information about the Locale that the message needs to be converted to and this is needed for internationalization. If I have a multi-lingual portal and output error messages in multiple languages, the spec needs to really consider what and where the charset for the HTTP header is going to be set. What if JSF realizes it needs to use UTF-8 but another tag library an application is using assumes fr_FR, who is correct and what will happen? How will JSF determine what encoding to use when it has Messages in ten different languages? What if the container starts writing the output to the stream before the header is set? Etc. etc.
This is possibly the most confusing and poorly written section in the entire document. This uses terms that don’t relate to anything, old class names and un-described tables. This needs to be re-written in a more concise way. I did not understand what a custom action was until I reached section 8.2.6 and realized that an action was really a tag implementation. Action is a poor choice of words because not all tags equate to actions. What is the action of an input tag? I understand action when talking about for-loop tags, but not input tags.
This seems quite contradictory to section JSF 2.8 because it leads the reader to believe that they have no control over the implementation of the use_faces tag and the method of saving the JSF state. That is UNTIL they read section 8.5. These two sections need to be combined to clarify the document.
I think that JSF is a very good idea in general and that it is a very complicated thing to define (due mostly to the use of HTTP, which is a stateless protocol). There are so many frameworks out there and each has its own benefits and downfalls. However, it is imperative that this specification attempt to solve as many problems as possible and not introduce any more. The spec must be flexible enough to support implementations that drive for speed and those that drive for flexibility. It must also support enormous amounts of flexibility internally because as vendors attempt to comply with it, they want to make as few changes to their own code base as possible.
Right now, JSF has not accomplished these goals. I think that it needs to consider a lot more than it has and really needs to address the more complex issues.
My boss made me dig into the JSF Framework and use it to develop a very simple project for sending newsletters. I read the PDF-book “JSF in Action” and wrote the application, at first being truly fascinated by JSF and almost ended up calling it “rubbish”.
I have one simple and profound point of criticism I want to state here:
!!! JSF provides only a subset of the possibilities any supported Mark-up-Language offers !!!
That sounds profane, but is the biggest contradiction to the celebrated RAD (Rapid Application Development) JSF pretends to enable. And let's not forget: Time's money!
I'll have to try to be more detailed and state, how I would have liked the framework to be implemented:
(Almost) every JSF UIComponent has a Renderer assigned, that translates it to the currently used Mark-up-Language like HTML or WML. There is much talk of Swing to, but I doubt JSF will ever run well with Swing User-Interfaces. (Yes, Backing-Beans have “Action-Listener “-Methods fully usable with Swing, but use the argument JSF-Action-Event to access UiComponents. And in turn UiComponents don't have renderers for Swing. Boom!) These Renderers can only traduce to Mark-up-code, they were “taught” to traduce to. Because JSF uses this render-technology, it does not work with e.g. JSP-code and even HTML-code as Tag-content. This is fatal!
I would have preferred the approach, I will outline by a processed Request-Response-Cycle. But first I have to state two sets of Objects, the Framework should be managing:
“GUI-Components” and, let's call them: “Backing-Beans”. (These Sets could be managed using XML, Databases or Java-Classes.)
A GUI-Component has these properties:
A parent GUI-Component, if needed, a set of child-components, also just if needed and most important a REPRESENTATION. This can be a JSP-File, a simple HTML-File, a SWING-Class or a AWT-Class. It is clear, that the rendering will be done using already implemented, widely known and well working Technology, WITHOUT LIMITING it's possibilities!
A Backing-Bean should have, let's call them: managed properties, and an optional reference to a GUI-Component. The properties are associated to e.g. Http-Request-Parameters or Properties passed via classic Action-Events, as thrown by SWING-Components. Now easily Validators and Converters, as stated in JSF, can be assigned to these managed properties. That's it for the population and validation. Backing-Beans, of course, have action-methods, that can be referenced in any GUI-Component.
Now to some short Request-Response-Cycle (Http): (Swing could be supported almost similarly.)
1) A Http-Request is sent to the Framework's Servlet, which instantiates and populates the Backing-Bean “myBean” according to the Backing-Bean-Configuration, e.g. done in “backingBeans.xml”. Then the “myBeans” Action-Method “doSomethingNice” as stated as Request-Parameter is called.
2) The Backing-Bean's method does something nice.
3) The Action-Method calls the Framework to retrieve Backing-Bean “theNextBean”, populates this Backing-Bean, and could even call some initializing methods, and returns it to the Servlet.
4) The Servlet looks up the GUI-Component referenced by “theNextBean” using e.g. “guiComponents.xml”.
5) Now the GUI-Components Representation is looked up. Is the Representation a JSP-File, a Request-Attribute “theNextBean” is set and the
“HttpServletRequest” is passed to the JSP. Is the Representation a "SWING-Class” some required Property , e.g. called “backingBean”, is set to “theNextBean”.
6) The used Technology renders the View, be it HTML, JSP, WML or SWING. No limiting Renderer is needed.
Using this, very hastily blueprinted Technology, the implementation of such genial UiComponents like the HTML-Data-Table would still be possible without limiting the used View rendering technology.
And what about the very useful state-management of JSF?
- Well, first of all it does not work, as promised. (e.g. any UiComponent of the select-family having a UiSelectItems as a child, will require the value-binding, if mapped to a Map, being available in any future Request. The Map is not stored in the View to decode incoming Requests.)
Furthermore state-management could be done by using a secure container, being referenced by a timestamped key. This Container can then be serialized and passed from Request to Request, or stored in the Session or even in some File or better Database on the Server. I prefer the latter one, not causing huge Traffic , nor being dependent on the hard to control HttpSession.
I beg your pardon for writing such a long pamphlet, but I thought a profound critique highly needed in times of hymns on a “over-engineered” framework.