Blog Archives

January 8th, 2010
9:30 pm
JSF 1.2/Facelets event & state handling

Posted under JSF
Tags , , ,

The issue here came about when trying to propagate click events from a child table pair tag to its parent facelet page. The table pair contained buttons to move rows between the tables, and to reorder rows on the target table – a typical design pattern used in this case to assign roles and rights to a user. The table pair tag is responsible for all the buttons for this function – move row selection left/right, move all left/right, reorder target row selection up, reorder target row selection down.

My general design in this situation is for the backing bean structure to mirror the objects on the page. There is therefore an overall page bean which has a child table pair bean for the table pair facelet tag, which in turn has 2 child table beans for its subsidiary facelet table tags. Whilst the parent facelet page does not need to know about the above button logic (it just pulls the result rows out of the child beans e.g. when a save is done), it does need to know when the child table pair has caused the page to be dirty, i.e. to have unsaved changes, which comes about when one of the above buttons is clicked.

My ideal solution to this would be to add an additional action listener on the table pair buttons – the main one is handled by the table pair bean, and an additional one on each button calls a single method on the overall page bean to notify that the page has changed. The parent does not need to know which button was clicked or why, but merely to know that a change has occurred. However this idea is scuppered in JSF 1.2 by the fact that a secondary f:actionListener tag on a button does not accept a method binding like the primary actionListener, but takes a fully qualified class name which must implement the ActionListener interface. This is a right pain as it is a class and not even an instance – you cannot tie the event to a particular bean.

My next attempt was to simply inject a parent reference in the TablePair bean in faces-config.xml, however this fails because JSF does not allow cyclic references in faces-config.

My final solution was therefore to pass a value binding for my own ChangeListener interface on the parent bean to the TablePair tag as a parameter, and declare this on each button using f:attribute. The TablePair bean then fetches the bean reference from the attribute when its actionListener is fired and calls the notify method on the reference’s Change Listener implementation. (I could also have used setPropertyActionListener to simplify this but an ICEfaces bug prevented this working – setPropertyActionListener was being called after the actionListener so the latter only ever saw a null value). The following code fragment illustrates what was used to pull the reference out of the attribute (note that this is incomplete and imports etc. are missing) :-

// Calling code
  private static final String CHANGE_LISTENER_ATTRIBUTE = "changeListener";
  ...
  ChangeListener changeListener =
    JSFUtil.fetchComponentAttribute(actionEvent, CHANGE_LISTENER_ATTRIBUTE);
  if (changeListener != null)
    changeListener.notify(this);
...
// Utility Class
public class JSFUtil {
  public static<F> F fetchComponentAttribute(ActionEvent actionEvent, String attribute) {
    UIComponent component = actionEvent.getComponent();
    Map<String, Object> attributes = component.getAttributes();
    return (F)(attributes.get(attribute));
  }
}

When propagating changes like this, it is important that the design does not cause recursive notifications, for example where a change gets passed up from one child to a parent, back down from the parent to all its children, who send it back up and so on. To this end, I therefore distinguish between the following concepts to avoid this happening:-

  1. Action Notification Events are only propagated upwards from children to parents, and are only raised in respect of external actions,  for example when a button click in a child tag causes a change which the parent needs to know about. ActionNotifications are never raised as a result of a property change on a component which could have been initiated by a parent. For clarity, if an external action causes a property change and needs to propagate this upwards, it is the fact that an external action occurred which is being propagated, and not the fact that a property has changed, i.e. in JSF terms it is the result of an action event and not a value change event. This means that whilst such an external action will pass an event up as well as changing a property, if a parent directly changes the same property, no event will be propagated up.  A child cannot directly change properties in its parent so it needs this mechanism to tell the parent “something external such as a button or link click has happened in me which you need to be aware of”. Typically this will be because a click action on the child has made the whole page dirty and the parent therefore needs to change component state throughout the page to reflect this (for example to enable the save and discard buttons and disable navigation from the page). As notifications only travel upwards, recursive notifications cannot therefore occur.
  2. Property Changes are only performed by a component on itself or on its child components. On itself, it can change any of its internal properties. On a child component, it can change any of the publically changeable properties of the child. As stated above, such changes will never give rise to action notification event propagation. However, property changes can certainly propagate downwards as required.

The state determination of a JSF page or a custom component can become complex when a number of components need to be, for example, selectively enabled and disabled depending on various property combinations. If the logic to determine the state is scattered throughout the component’s managed bean, or even worse, is coded in value expressions on a JSF page, it is hard to make sense of the state determination logic, easy to miss logic that is required, and easy to break the state determination when the code is changed. Therefore, I always use a private changeState method on a bean to perform all the state determination and changes. Typically this will involve a ladder of if..else based logic which checks properties on the bean, and then for example sets or clears various enable/disable properties for the JSF components. In State Machine terms, the various properties of the bean are inputs to the changeState method, and the method uses these inputs to determine a new state for the bean, setting various properties for the new state. I am not fussy about the precise implementation of this – in complex cases, it may be worth using a state machine/state table driven approach to determine state, and maintain a ‘current state’ for the bean which is independant of the beans properties, but for most normal cases this is overkill. What is important is to use an implementation which is clear, correct and easy to maintain, and where the mechanism is easy to understand and flows naturally from the state change requirements. This method should be called whenever a change happens to any of the inputs which the method uses to determine state, and therefore will normally be called many times throughout the bean. If AOP is in use, this might be a good candidate for using a pointcut and advice to dynamically insert the calls, for example on various property changes. In typical cases, I end up with a dirty flag on the bean which indicates that something has changed, and the changeState method checks the flag and sets various enable/disable properties as required. It is therefore often worth having an overloaded version of changeState which allows new values of such inputs to be passed in and set, and then the state change logic performed, in a single call.

As mentioned earlier, I specifically do not perform any such logic on a JSF page. The presence of logic in value expressions on a JSF page is a warning bell as it may indicate that either MVC controller logic or worse,  business logic has been placed on the page. As an example, my TablePair bean allows the ‘move selected rows to destination’ button to be clicked if any rows have been selected in the source table – otherwise the button is disabled. It would be possible to code an ‘anyRowsSelected’ property on the bean, and call this property directly from the disable attribute on the JSF page. Whilst this is a simple example, I would contend that this effectively places a controller logic decision in the MVC view. The correct way would be for the disable property on the button to directly refer to an enable/disable flag on the bean, and for the changeState method in the bean to call anyRowsSelected as a method, and set the enable/disable flag as required. This removes all evidence of the logic from the view, and also means that if the logic changes, for example if other conditions can occur on the bean which affect the button state, the change is made in the correct place – only in the changeState method on the bean. The JSF page would not need to be touched and has no knowledge of this.

No Comments »

January 8th, 2010
9:28 pm
ICEfaces components missing from Eclipse Palette

Posted under Eclipse
Tags , , , , ,

I had an Eclipse Galileo workspace containing several projects, and for some reason some of the projects did not show a full palette of components when opening a jspx file using the Web Page Editor. The main culprit was the ICEfaces components set which was missing. The workspace as a whole was clearly OK, but some projects had become broken. I now believe that some changes I made to user library locations may have caused the problem, but not sure on this.

Firstly, I visited the JSF project facets screen by right clicking the project in the explorer and selecting Properties to open the project properties page, then opening the  Project Facets entry in the left hand pane. I removed (unticked) support for ICEfaces and saved the changes. Then I added it back and saved again. This did not fix the problem.

I looked at the JSF Tag Registry view which lists all the Tag libraries registered for a project. This can be displayed by clicking menu option Window/Show View/Other and then entering Tag in the search box at the top. Select Tag Registry under JSF and the view will open. You must select the desired project in the view as it does not default to the current project. You can then expand the entries to see the Tag libraries registered. If you select one of the top level nodes on the registry tree (in my case these were labelled Facelet Tag Registry and JSP Tag registry) you can click the refresh button adjacent to the project selection button. This refreshes the entries, and you can elect whether or not to flush the cache in the resulting dialog. Unfortunately it was of no help to me in fixing the above problem, and refreshing/clearing the cache did not clear the issue. However, this view could be useful to browse Tag Library registrations.

I was aware that the palette entries are driven by the available Tag libraries on the project Build path, so still felt that it was library related. I then revisited the project properties page, and this time expanded the Project Facets entry in the left pane rather than clicking on it. I then selected Java Server Faces. This listed the user libraries for the project in the right hand pane, including all of the ICEfaces and JSF ones. I deselected all but one of them (you cannot deselect all of them), leaving the JSF 1.2 (Sun RI) library selected. I then applied/saved the changes and closed the screen. I then re-opened it, selected all the originally selected libraries and applied/saved again. This time, when I opened a jspx file in the project with the Web Page Editor, the ICEfaces components were present on the palette.

One last glitch was that after doing this, the palette entries for ICEfaces only had icons present, no descriptions. I then  closed the web page editor window, and closed Eclipse down normally, and re-opened the same workspace in Eclipse again. I then re-opened the same jspx in the Web Page Editor, and this time the ICEfaces components were all present with both the Icons and the descriptions. Problem solved!

No Comments »

January 8th, 2010
4:20 pm
Adding jsf view state to domain objects

Posted under JSF
Tags , ,

A classic example of this is the need to add a selected flag to each row if you are using row selection with an ICEfaces table.

The fundamental point here is that you do not want to pollute the domain objects with state that is specific to the view – in this case, the flag is merely a convenience for supporting the user interface.

This post details a good solution to this problem, which is to use the decorator pattern to decorate the row domain objects with a decorator containing the row selected flag. Often, a decorator has an identical interface to its decorated object, but that is not always the case, and in this case we actually need to add a property. This does however mean that you have to be aware of which class you are using at a given point in the code, and you cannot use a generic decorator interface to declare the concrete decorators if they have new properties added. Also, if you have a number of such decorators, you cannot wrap the domain objects with them transparently in turn for the same reason. You can get around some of this with some clever use of reflection, but it does complicate matters and impact performance.

The ICEfaces page on row selection may be found here.

No Comments »

January 8th, 2010
3:25 pm
JSF: #{…} is not allowed in template text

Posted under JSF
Tags , , , , ,

This error can occur when loading a JSF/Facelets page :-

org.apache.jasper.JasperException: /home.jspx(16,17)
   #{...} is not allowed in template text

One reason for this, described on JavaRanch here, is that the JSF page is not being routed properly via the servlet mapping in web.xml. The following extract from web.xml shows a mapping for .iface, to route urls ending in .iface to the ICEfaces Persistent Faces Servlet:-

    <servlet-mapping>
        <servlet-name>Persistent Faces Servlet</servlet-name>
        <url-pattern>*.iface</url-pattern>
    </servlet-mapping>

Even though the page itself may be a .jspx file, using .jspx rather than .iface in the url would not route the page to the above servlet, causing it to be parsed incorrectly. This post describes the cause in more detail – the #{…} syntax is unified EL, which is not allowed in template text in a JSP (hence the error). In the above case the page was being treated as a JSP rather than a Facelet due to the incorrect routing.

No Comments »

January 8th, 2010
10:42 am
ICEfaces facelets strips DOCTYPE, puts IE in quirks mode

Posted under JSF
Tags , , , , ,

By default when you create a new ICEfaces Facelets project with a sample page, it codes the DOCTYPE directive directly. Unfortunately, this is stripped out during processing/rendering and does not  appear in the final HTML for the page. When running IE without a suitable DOCTYPE directive, it switches into Quirks Mode and is not fully standards compliant, which may cause pages to display incorrectly.

the DOCTYPE can be added back by using the <ice:outputDeclaration> tag. To do this, you also need to add an <f:view> tag as you would in JSP mode, as in the following example :-

<?xml version="1.0" encoding="UTF-8"?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:ice="http://www.icesoft.com/icefaces/component">
 <ice:outputDeclaration
  doctypeRoot="HTML" doctypePublic="-//W3C//DTD XHTML 1.0 Transitional//EN"
  doctypeSystem="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
 <html>
    <head>
    ...
    </head>
    <body>
    ...
    </body>
 </html>
</f:view>

The issue is discussed and solved in this ICEfaces forum post. Interestingly, a page created by ICEfaces for a  JSP (non-facelet) project also uses the <ice:outputDeclaration> tag, presumably for the same reason.

Note that you cannot omit the <f:view> tag and add the xmlns namespace declarations to the <ice:outputDeclaration> tag as this fails – the <f:view> tag needs to be present.

Another post about Quirks mode and DOCTYPE switching, which also contains a useful Bookmarklet (Javascript link) which will tell you directly what mode a page is running in, may be found here.

No Comments »

January 8th, 2010
10:22 am
Useful reference/tutorial sites on Facelets

Posted under JSF
Tags , , , ,

I have found the following sites useful :-

Tutorials

Reference Information

No Comments »

January 7th, 2010
7:33 pm
Some useful Sites / Tutorials about JSF & Facelets

Posted under JSF
Tags ,

Helpful simple post about how facelets actually works.
http://www.theserverside.com/discussions/thread.tss?thread_id=41855

JSF central Inside Facelets tutorial series :-
http://www.jsfcentral.com/facelets/

IBM Developerworks articles (can also be downloaded as PDFs from the sites)

Facelets :-
http://www.ibm.com/developerworks/java/library/j-facelets/

JSF for nonbelievers articles – good introduction to JSF:-
http://www.ibm.com/developerworks/java/library/j-jsf1
http://www.ibm.com/developerworks/java/library/j-jsf2/
http://www.ibm.com/developerworks/java/library/j-jsf3/
http://www.ibm.com/developerworks/java/library/j-jsf4/

No Comments »

January 7th, 2010
5:55 pm
Using the ICEfaces Component Showcase CSS and icons as a template

Posted under JSF
Tags , , ,

This tutorial describes how to use the Component showcase css and icons as the template for your own project.

I’ve not looked into it in detail, but it certainly makes sense to use the same look and feel and borrow from ICEfaces where necessary.

One of the comments is less than complementary about some of the CSS code in the example.

No Comments »

December 17th, 2009
5:12 pm
Correct Scoping/Separation of JSF Managed Beans

Posted under JSF
Tags , ,

This ICEfaces article details the importance of the correct separation of concerns and scoping of JSF managed bean. Of particular importance is ensuring that you do not mix up the layers of the MVC design pattern, by mashing up different MVC concerns into a single managed bean. Correct splitting up of classes and scoping can avoid this and achieve the desired loose coupling.

The approach I have taken, which differs subtly from the above article but is fundamentally the same, is as follows :-

  1. I encapsulate all calls to the business/service layer in a ModelBean. This bean exposes properties which hold all the business data fetched from the service layer, and various populate and save methods to fetch/populate those properties and finally persist modified versions of them back via the service layer. As I am using JPA and have generally elected not to use the DTO pattern,  the properties  are JPA entities, objects which are the result of JPA select constructor expressions, or primitive data values from the database. For clarity, the ModelBean is stateful and session scoped and so holds the properties all the time a page is being viewed/edited, whereas all the calls to the service layer are stateless. I might have a single model bean, or I might break it down into a number of separate beans, depending on what suits the design. Whilst there could be one per JSF page, typically I find that there is scope for a lot of re-use of common methods and properties acrosss pages. Conversely, for a larger application, it may become unmodular and unwieldy to have a single model bean. A fundamental point about this bean is that it does not  perform any controller logic, i.e. does not directly interact with the components on the page (although typically of course they will refer to its properties to get data).
  2. I encapsulate all the logic which interacts with the components on the page in a controller bean for the page. Where the page contains subcomponents such as custom facelets tags (in my case, a TablePair tag is an example of this), I typically find that a good design is to have a separate child controller bean for each custom component, so that the controller mirrors the structure and requirements of the view. These controller beans do not access the business/service layer directly – all such access is routed via the ModelBean above. This separates all code which is directly aware of the business layer interface from controller code which is aware of the structure and handling of the page.
  3. I ensure that the view (the JSF page, facelets and tags) does not contain any business or controller logic. As this post indicates in its last paragraph, the presence of logic expressions in JSF value expressions is often a warning bell that this may have occurred, and the view has been polluted with controller or model concerns. For example, the disable attribute on a JSF component is strictly a property reference to an enable/disable property in a controller bean. The conditions under which that property is enabled or disabled are strictly a controller issue. The above post also details design guidelines for state change management and event handling and propagation for the controller bean.

 

A good test of the design is to ask yourself the following questions:-

  1. What would need to change if the call interface to the service layer changed? Would it be necessary to change any backing beans which also contain controller logic – which handle components on the page? If so, the design has become polluted. Consider a possible requirement where the service layer interface was enhanced, and the old interface was eventually due to be deprecated. You might have a situation where you needed to support both versions. Would this result in having 2 identical copies of some controller code which interacts with components on the page? If so, you have polluted the design and mixed controller concerns in with the model. If you had to perform any bug fixes on the duplicated controller code, you would have to update both copies identically to keep them in step, and so have broken modularity.
  2. Conversely, what would need to change if the user interface to the page changed, but performed the same functions in terms of the model (perhaps the interface was improved to make it more user friendly)? Would it be necessary to change any beans which contain calls to the business/service layer? If so, the design has again become polluted. Consider a possible requirement where you needed to maintain both the old and the new versions of the user interface for a period until the old one had been completely phased out. This would require 2 versions of the controller beans to be maintained. Would this result in having 2 identical copies of some model code which directly calls the business/service layer? If so, you have polluted the design and mixed model concerns in with the controller. If you had to perform any bug fixes on the duplicated model code, you would have to update both copies identically to keep them in step, and so have broken modularity.

Comments Off on Correct Scoping/Separation of JSF Managed Beans

December 17th, 2009
4:15 pm
Using Eclipse/JSF/JPA with Tomcat 6

Posted under JPA
Tags , , , , , ,

I’ve found that this is useful for prototyping/mockups of apps that are targetted for GlassFish. It is possible to run JPA with Eclipselink outside an EJB container, so a JSF/JPA app can be run under Tomcat, resulting in less overhead and faster turnaround of changes. For a while I’ve had to use a PC which is RAM limited, and so developing/prototyping with Eclipse and Glassfish has been slow. Turning around deployments/changes around takes time, and I’ve found the synchronisation between Eclipse and Glassfish to be a bit fussy – sometimes Eclipse misunderstands the state of Glassfish, needing a Glassfish restart which again takes valuable time.

Note the following points on doing this:-

1/ My application stack looks similar to the ‘real’ one, but my Service layer/domain objects are just POJOs which are explicitly created or injected via faces_config.xml. This Oracle Example details the various IOC features of the JSF. managed bean facility.

2/ Persistence.xml needs setting up differently to run JPA outside the container. I have found it easiest to specify the database connection explicitly, rather than using a data source. In Eclipse, you can use the persistence.xml editor to populate the connection properties directly from the one Eclipse uses for its entity validation. Whilst you can do JNDI lookups of a data source stored in Tomcat, the naming context used is different, as it makes use of the Enterprise Naming Context (ENC), i.e. “java:comp/env”. This example details how to do it if you want to go that way. A sample persistence.xml follows (with entries commented out where they have been replaced for use with Tomcat) :- 

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

 <!--<persistence-unit name="SentryPrototype" transaction-type="JTA">-->
 <persistence-unit name="SentryPrototype" transaction-type="RESOURCE_LOCAL">

   <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

   <!--<jta-data-source>jdbc/JPATestPool</jta-data-source>-->

   <class>uk.co.salientsoft.jpatest.domain.UserInfo</class>
   <properties>
    <property name="eclipselink.logging.level" value="INFO" />

    <!-- <property name="eclipselink.target-server" value="SunAS9" />-->
    <property name="eclipselink.target-server" value="None" />

    <property name="eclipselink.session-name" value="SentryPrototypeSession" />
    <property name="eclipselink.target-database" value="Oracle" />   
    <property name="eclipselink.ddl-generation.output-mode" value="database" />

    <property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
    <property name="eclipselink.jdbc.user" value="sentry"/>
    <property name="eclipselink.jdbc.password" value="sentry"/>
    <property name="eclipselink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>

   </properties>
  </persistence-unit>
</persistence>

 

3/ Ref this eclipse tutorial :-
Tomcat does not have an EJB container so you must add EJB 3.0/JPA 1.0 capability for EclipseLink JPA by placing the specification persistence.jar into the container lib directory $TOMCAT_HOME/lib.
It is recommended to put persistence_1_0.xsd there as well.  It is not recommended that the WAR include its own version of persistence.jar. Your eclipse project should reference but not include this jar and xsd.

The eclipselink.jar should be placed off of the container lib directory $TOMCAT_HOME/lib.
Since Tomcat does not include an EJB container, you may put eclipselink.jar in the web applications’s lib directory or higher up in the classloader by putting it off of Tomcats’ lib directory, where all web applications can access it.
Do not split the eclipselink.jar from the javax.persistence jar – keep them together – preferably in $TOMCAT_HOME/lib

 4/ Tomcat has its own dependencies on the Expression Language (EL) web libraries. These should be removed from WEB_INF/lib when deploying to Tomcat as pointed out here. (If you do not do this, the application will crash with duplicate class loading exceptions.) This may be done in eclipse on the Java Server Faces facet page – open the project properties for the project, and select Java Server Faces under Project Facets. Untick the entry for Standardized EL Library v1.0.

Then save the changes and redeploy the application.

For more information, the eclipse tutorial referenced in 3/ goes into greater depth on the subject. You can also find a list of the available eclipse JPA tutorials here.

5/ When running xxxxxx

Comments Off on Using Eclipse/JSF/JPA with Tomcat 6