ICEfaces 1.x Compatibility

Table of Contents

ICEfaces 1.x Compatibility

Overview

The current version of ICEfaces has been developed specifically to take advantage of the improvements, optimizations, and new features of JSF 2, however, developers with existing ICEfaces 1.x applications that want to move their applications to use the latest ICEfaces and JSF 2 want to do so with minimal disruption and effort. To provide as smooth a migration as possible for developers that want to port their applications, ICEfaces provides a compatibility layer to help reduce the resources required to move an application from ICEfaces 1.8.x to run on the current ICEfaces release. This section of the documentation outlines what the different parts of the compatibility layer are as well as noting areas of an application that may need to be modified or updated.

Page Description Language - JSP and Facelets

In JSF 1.x, the standard mechanism for describing pages is JavaServer Pages (JSP), however, as the use and adoption of JSF increases, JSP is seen as a less than optimal solution for page development and alternatives were developed. The most popular of these is Facelets and it has now been adopted as the new standard page description language for JSF 2.

Facelets

New applications must be developed in Facelets. Existing applications that use Facelets can be migrated with little or no modifications to the pages.

JSP

JSP development is not supported by ICEfaces 2+. All development should be done in Facelets.

Porting

Here are some of the things you may need to adjust as you move your applications from ICEfaces 1.8.x to the current version:

  • The <ice:outputDeclaration> component is no longer required. You can now use a regular DOCTYPE declaration.
  • The <f:view> tag is not strictly required. However, if you do have it in your page, then it should be nested within the <html> tag and not outside of it.
  • When using JSTL with Facelets in JSF 2, use the following namespace in your .xhtml pages:
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    
  • Replace <ice:ice:outputHtml> with <html>
  • Replace <ice:ice:outputHead> or <head> with <h:head>
  • Replace <ice:ice:outputBody> or <body> with <h:body>
  • In ICEfaces 1.x, the Facelets implementation was included, and one feature that was provided was that html tags were made into full components, in a one-to-one mapping, instead of the regular Facelets behavior of html fragments becoming UIInstructions, where one html tag might become several UIInstructions components, or several html tags might become one UIInstructions component, depending on their arrangement. That feature resulted in a component tree hierarchy that was more what one would expect, and solved the problem of using html tags within containers like h:panelGrid, which relies heavily on the count and arrangement of its children. Since JSF 2 includes its own Facelets runtime, this feature is no longer provided. The work-around is to not use html tags directly within containers like h:panelGrid, and instead put them within another container such as h:panelGroup. Alternatively, ICEfaces EE Core Framework Extensions includes an updated and re-engineered version of this feature to ease your porting efforts.

Configuration

JSF 2 provides a number of annotations to make configuration easier with JSF 2 applications. In fact it's possible to have an application that has no faces-config.xml file at all. Additionally, ICEfaces takes advantage or the various extension points and features provided by JSF 2 for better and more compatible integration.

Porting
  • In ICEfaces 1.8.x, it was necessary, when using Facelets, to specify a custom ViewHandler in your faces-config.xml file. This is no longer required and should be removed from your configuration.:
<application>
    <view-handler>com.icesoft.faces.application.D2DViewHandler</view-handler>
</application>
  • The custom servlets and mappings specified in ICEfaces 1.8.x applications are no longer required:
<servlet>
    <servlet-name>Persistent Faces Servlet</servlet-name>
    <servlet-class>com.icesoft.faces.webapp.xmlhttp.PersistentFacesServlet</servlet-class>
    <load-on-startup> 1 </load-on-startup>
</servlet>

<servlet>
    <servlet-name>Blocking Servlet</servlet-name>
    <servlet-class>com.icesoft.faces.webapp.xmlhttp.BlockingServlet</servlet-class>
    <load-on-startup> 1 </load-on-startup>
</servlet>

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

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

<servlet-mapping>
    <servlet-name>Blocking Servlet</servlet-name>
    <url-pattern>/block/*</url-pattern>
</servlet-mapping>
  • If your application runs in compatibility mode and uses the ICEfaces 1.8 dynamic resource API directly or uses components that use the dynamic resource API (OutputResource, DataExporter, HtmlGraphicImage, InputRichText), you must configure the CompatResourceServlet and servlet mapping to ensure that the resources are properly handled for JSF 2. Add the following to the web.xml of you application:
<servlet>
    <servlet-name>Resource Servlet</servlet-name>
    <servlet-class>com.icesoft.faces.webapp.CompatResourceServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Resource Servlet</servlet-name>
    <url-pattern>/xmlhttp/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/icefaces/*</url-pattern>
</servlet-mapping>
  • When using compatibility mode the following configuration is recommended (in the web.xml file) to emulate expected behavior that was included in the ICEfaces 1.8 Facelets implementation:
<context-param>
        <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
        <param-value>true</param-value>
</context-param>
  • When using compatibility mode the following configuration is recommended (in the web.xml file) to ensure consistent behaviour when using partialSubmit and validation tags (e.g. f:validateLength) when the Bean Validation library is involved:
<context-param>
        <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
        <param-value>false</param-value>
</context-param>

Scopes

By default, ICEfaces 1.x operated under what was referred to as extended request scope. In a nutshell, extended request scope refers to the behavior that a new request is only associated with a change in view. This means that Ajax requests that occur within an existing view are not treated by ICEfaces as new requests. A request is not considered a new request unless it results in a new view so request-scoped beans would not be recreated until a new view was created. This behavior was configurable to allow for the more standard definition of request scope but was considered necessary at the time because the existing standard scopes (request, session, application, none) were not sufficient for supporting ICEfaces features like partial submit and Ajax Push.

In addition to the View scope provided by JSF 2, ICEfaces introduces a custom scope called Window scope. This new scope is designed to fill a gap in the existing scopes available for JSF 2. A Window-scoped bean exists for the life of a browser window or tab but is also built to survive reloads and refreshes. This means it can last over the life of multiple ICEfaces views (Window Scope does not persist across non-ICEfaces views).

Porting

Starting with ICEfaces 2, extended request scope is no longer supported so if your application was relying specifically on this behaviour, you may need to adjust the scope of your beans. The options are:

  • Request: This scope is provided by JSF 2 and lasts briefly for the duration a single user event or render. It is useful for transient communication between components or beans on the same page.
  • View: This scope is provided by JSF 2 and lasts the duration of a view. This would typically be the closest match for the old extended request scope behaviour.
  • Flash: This scope is provided by JSF 2 and is a short, conversation-style scope that exists for a single view transition, including reloads.
  • Window: This scope is provided by ICEfaces and lasts for the duration of a browser window. It is a good replacement for Extended Request Scope for state that is expected to survive a browser reload. As there is a mechanism for providing and using custom scopes in JSF 2, you can specify that your bean use Window scope by simply adding the correct annotation. For example:
@ManagedBean(name = "windowBean")
@CustomScoped(value = "#{window}")
public class MyBean implements Serializable {
...

Both View Scope and Window Scope allow beans to be associated with individual views, thereby allowing the application to handle multi-tab/multi-window use. The choice of which one to use depends mainly on the expected behavior under the browser reload button. If "reload" should be a "reset" (clearing state in the current view) then View Scope should be used. If "reload" should be a "refresh" (having little or no impact on the application) then Window Scope should be used.

Using @ViewScoped Beans

While @ViewScoped beans are a welcome addition to JSF, they do not behave identically to the older extended request scope beans from ICEfaces 1.x. Some things to keep in mind while migrating:

  • Using component bindings with @ViewScoped beans is strongly discouraged. Due to a known bug in JSF 2.1 (http://java.net/jira/browse/JAVASERVERFACES-1492), @ViewScoped beans are not created until after the view has been restored, meaning they are not available when the binding typically occurs. Component bindings are not recommended in general so, if possible, you should consider modifying the design of your application to avoid using them. If that's not possible you should consider using @RequestScoped beans with the bindings.
  • Related to the point above, using <c:forEach> or <c:if> tags with @ViewScoped beans leads to similar issues (see http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-928). Those tags are handled during the Restore View phase when the @ViewScoped beans are not available. If you are using those tags, you should either change the scoped of the beans involved or, in the case of <c:forEach>, replace it with the Facelet tag, <ui:repeat>.

These issues should be fixed in both the spec and implementations of JSF 2.2. It also appears to be fixed in Mojarra 2.1.18 and above.

Components

The current version of ICEfaces includes a version of the ICEfaces 1.8.x component suite that has been modified and tested to work with the latest ICEfaces core framework. This provides developers with a couple of benefits. First, the standard JSF components that come with the JSF implementation are fully supported by ICEfaces so you can start building ICEfaces-enabled applications immediately using those components. However, the basic set of components is typically not sophisticated enough for most applications. They require a richer set of components like those found in the ICEfaces 1.8.x framework. By including a library of compatible ICEfaces 1.8.x components, developers have immediate access to a large, mature, well-tested component suite. Additionally, for those existing ICEfaces 1.8.x applications that are being considered for migration to a newer version of ICEfaces, the compatible component library allows full support for all the components that developers are currently using, making it much simpler to port the application.

The compatibility layer for components comes in one library:

  • icefaces-compat.jar: This library is the full set of custom and extended components from ICEfaces 1.8.x, updated to run on JSF 2 and the current ICEfaces framework.

Simply including this library with your application provides access to the components previously available in ICEfaces 1.8.x.

The following ICEfaces 1.8.x Component Suite components are no longer present in ICEfaces:
  • ice:inputFile (use ace:fileEntry instead)
  • ice:outputDeclaration (use <!DOCTYPE ...> instead)
  • ice:outputBody (use h:body instead)
  • ice:outputHead (use h:head instead)
  • ice:outputHtml (use <HTML> tag instead)
  • ice:portlet (unnecessary now, simply remove it)
Porting
  • Using the compatible component library means that there are no changes or adjustments to the vast majority of components, either in the page markup or in the backing beans, when porting an ICEfaces 1.8.x application.
  • With ICEfaces 1.8.x, the ice:portlet component was used to namespace and uniquely identify each portlet on a page. With ICEfaces 2+ and the portlet bridge, this component is no longer required or supported and should be removed from the page markup.
  • The ICEfaces compatible component library contains additional protection against cross-site-scripting attacks. It is possible that existing applications have been relying on the ability to render HTML markup into text labels. If so, the application will need to be modified to make use of outputText with its "escape" property set to false.

JavaScript API

The client-side JavaScript API for the current version of ICEfaces has changed from the ICEfaces 1.8.x version. The new API is described in detail in the JavaScript Client API section.

For compatibility and porting purposes, the original API from ICEfaces 1.8.x is still available in the compatibility library. For the most part, these are now just wrapper methods that call into the more current ICEfaces API.

Porting

Usage of the client-side JavaScript API is mostly transparent. The components that use the ICEfaces 1.8.x API will now simply use the wrapper versions of the older methods which end up calling through to the current ICEfaces APIs. If your application is calling the older API directly, you should see the same benefit.

Server-side API

Although we've made every attempt to make the latest releases of ICEfaces as compatible as possible, there are some APIs that have changed or been dropped since 1.8.x.

Porting
  • The com.icesoft.faces.context.DisposableBean class is no longer available. Instead, use the JSF2 @PostConstruct and @PreDestroy annotations on methods that you would like called after your bean has been constructed and before it goes out of scope.

Ajax Push

ICEfaces now uses the ICEpush product for Ajax Push. For information on porting to or using Ajax Push in the current release of ICEfaces, see the documentation on Ajax Push - APIs.

Portlets

You can now build and run your portlets under ICEfaces using the PortletFaces Bridge. You can find more details about running the examples and building your own porlets in the Portlet Development section.

Porting

To port your existing portlets to use the current release of ICEfaces and the PortletFaces Bridge you should:

  • Modify your portlet.xml file to use the PortletFaces Bridge servlet. See the section on the portlet.xml file for more information.
  • Ensure you are using all the proper libraries. See the section on Portlet Library Dependencies for more information.
  • Remove the <ice:portlet> tag from your page markup. This component is no longer required or supported.

External Scripts

Certain components may rely on external 3rd-party scripts that will not work correctly unless the script is loaded and made available in the <head> on the initial GET request for the page. This can be difficult for components that might get added or rendered out dynamically after the initial page render.

ICEfaces includes a feature for annotating the components that need this type of support for external scripts.

@ExternalScript(scriptURL="_urlToScript_",
                contextParam="_contextParameterKey_" )
public class MyComponentRenderer...

The annotation specifies the location of the script as well as the context parameter required to be set. If the component with the annotation is detected and the context parameter is set, then the script link will automatically be rendered out to the <head> of the document on the initial render.

Dynamic Script Evaluation

The com.icesoft.faces.context.effects.JavascriptContext API, used for sending Javascript code from the server to the client for evaluation, continues to be available for use. New applications are encouraged to instead use the org.icefaces.util.JavaScriptRunner API, which is significantly simpler, with only one method: org.icefaces.util.JavaScriptRunner.runScript(javax.faces.context.FacesContext context, java.lang.String script).

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

© Copyright 2014 ICEsoft Technologies Canada Corp.