Migrating from JSF 1.2 to JSF 2.0
Painfulness
Painfulness of upgrading JSF 1.2 to 2.0 depends on the view technology which you are currently using and which you want to use.
- JSP 2.x to JSP 2.x = Almost no effort.
- Facelets 1.x to Facelets 2.0 = Little effort.
- JSP 2.x to Facelets 2.0 = Lot of effort. Double this if you also have custom components.
Basic changes
Regardless of the view technology switch, at least the following steps should be done:
- Remove JSF 1.2 JAR's from
/WEB-INF/lib
(if any). - Drop JSF 2.0 JAR's in
/WEB-INF/lib
(if JSF 1.2 was servletcontainer-supplied, you might want to change the classloading policy to load webapp libraries first before servletcontainer libraries, see also JSF2 classloading issues in application servers). Update root declaration of
faces-config.xml
to comply JSF 2.0 spec.<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">Note: when you're using JSF 2.2 or newer, use the
http://xmlns.jcp.org
namespace domain instead ofhttp://java.sun.com
throughout the above XML snippet.Ensure that root declaration of
web.xml
already complies at least Servlet 2.5. JSF 2.0 won't work on 2.4 or lower (although it's hackable).<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="YourWebappID"
version="2.5">Note: when you're using Servlet 3.0 or newer, use the
http://xmlns.jcp.org
namespace domain instead ofhttp://java.sun.com
throughout the above XML snippet.
JSP 2.x to JSP 2.x
If you're using JSP 2.x and want to keep using it, then you basically don't need to change anything else.
Gradually upgrading
If you're already using a suffix url-pattern
for the FacesServlet
, like *.jsf
, then it's good to know that the FacesServlet
will first scan for *.xhtml
file and if it is not present, then scan for *.jsp
file. This provides you room to gradually convert from JSP to Facelets behind the scenes without changing the URL's.
But if you're using a prefix url-pattern
, like /faces/*
and you want to gradually upgrade from JSP to Facelets, then you really have to change it to *.jsf
and possibly also all links in the existing JSP pages.
You only need to keep in mind that the new JSF 2.0 provided implicit navigation doesn't scan for the presence of the file, it will go to outcome.xhtml
anyway. So if you want to come from or go to *.jsp
, then you still need to include it in the viewid the JSF 1.x way.
Facelets 1.x to Facelets 2.0
If you're using Facelets 1.x as view technology and want to use the JSF 2.0 supplied Facelets 2.0, then you need to do the following additional steps:
- Remove Facelets 1.x JAR from
/WEB-INF/lib
. - Remove Facelets 1.x
FaceletViewHandler
fromfaces-config.xml
. - Any custom
FaceletViewHandler
implementation needs to be updated to extendViewHandlerWrapper
instead. - Not necessary, but just for cleanup, remove any Facelets 1.x related
<context-param>
values fromweb.xml
which are already default in Facelets 2.0, like thejavax.faces.DEFAULT_SUFFIX
with value of*.xhtml
. Update root declaration of existing Facelet taglib XML's to comply Facelets 2.0.
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">Note: when you're using JSF 2.2 or newer, use the
http://xmlns.jcp.org
namespace domain instead ofhttp://java.sun.com
throughout the above XML snippet.
That should basically be it.
JSP 2.x to Facelets 2.0
If you're using JSP 2.x as view technology and you want to upgrade to Facelets 2.0 immediately, then you need to do a lot of changes before the site can go live. You're basically changing the view technology here.
Master page changes
On every master page, you need to change the following basic JSP template..
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE html>
<f:view>
<html lang="en">
<head>
<title>JSP page</title>
</head>
<body>
<h:outputText value="JSF components here." />
</body>
</html>
</f:view>
..to the following basic Facelets template:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>XHTML page</title>
</h:head>
<h:body>
<h:outputText value="JSF components here." />
</h:body>
</html>
Note: when you're using JSF 2.2 or newer, use the http://xmlns.jcp.org
namespace domain instead of http://java.sun.com
throughout the above XHTML snippets.
Include page changes
If your existing JSP pages are well designed, you should not have any line of scriptlet code and you should also have only the <jsp:include>
as the sole JSP-specific tag. Any of those needs to be changed from:
<jsp:include page="include.jsp" />
to
<ui:include src="include.xhtml" />
The basic JSP include page template of..
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<f:subview id="include">
<h:outputText value="JSF components here." />
</f:subview>
..should be changed to the following basic Facelets include page template:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:outputText value="JSF components here." />
</ui:composition>
Note: when you're using JSF 2.2 or newer, use the http://xmlns.jcp.org
namespace domain instead of http://java.sun.com
throughout the above XHTML snippets.
Custom component changes
You need to change the JSP TLD files to Facelets TLD files as described in this Mojarra Migration Guide.
Aftermath
Regardless of the migration approach, you can gradually eliminate the faces-config.xml
by the new JSF 2.0 annotations or even CDI. Any <managed-bean>
can be annotated by @ManagedBean
:
@ManagedBean(name="managedBeanName")
@RequestScoped
public class SomeBean {}
Next to @RequestScoped
, there are also @ViewScoped
, @SessionScoped
and @ApplicationScoped
available. If you omit the name
attribute of the @ManagedBean
, then it will default to classname with the 1st char lowercased.
@ManagedBean
@RequestScoped
public class SomeBean {}
In this particular example, it will be #{someBean}
.
Any <managed-property>
can be annotated using @ManagedProperty
:
@ManagedProperty("#{otherBean}")
private OtherBean otherBean;
Any <validator>
can be annotated using @FacesValidator
:
@FacesValidator("someValidator")
public class SomeValidator implements Validator {}
Any <converter>
can be annotated using @FacesConverter
@FacesConverter("someConverter")
public class SomeConverter implements Converter {}
Any <renderer>
can be annotated using @FacesRenderer
@FacesRenderer(componentFamily="someComponentFamily", rendererType="someRendererType")
public class SomeRenderer extends Renderer {}
Any <navigation-case>
which uses the filename of the XHTML page as both <from-outcome>
and <to-view-id>
can be removed since this will be implicitly done. This can be gradually done by changing all outcome values to match the filename of the target view.
Finally, any session scoped bean which was been put in the session with the sole reason to retain the bean data in subsequent requests in the same tab/window can better be marked @ViewScoped
, because this way the bean won't be affected when the enduser opens the same page in different tabs/windows.
Component libraries
Note that I don't take any 3rd party componant libraries like PrimeFaces/RichFaces/IceFaces into account in this answer, it would then be impossible to write a reliable answer since it basically boils down to "it depends". In general it's sufficient to just upgrade the component library to a -by themselves verified- JSF 2.0 compatible version as per their instructions. Best is to just write unit tests, run them before and after the upgrade and fix any issues individually.
Here are at least some useful links with regard to migration of the specific component library:
- RichFaces Migration Guide - 3.3.x to 4.x migration
- IceFaces 2 Wiki - IceFaces 1.x Compatibility Guide
PrimeFaces has no migration guide for PrimeFaces 1.x to 2.x as PrimeFaces 1.x requires Facelets 1.x already, so you just have to follow Facelets 1.x to 2.x migration steps. However, there's a PrimeFaces 2.x to 3.x (and higher) migration guide which might apply as well on migrating from PrimeFaces 1.x to 3.x (or higher). Tomahawk has also no migration guide. Basically the only which you need to change are the JARs and if necessary get rid of all <t:saveState>
references on a request scoped bean by making the bean view scoped.
How to replace JSF 1.2 with JSF 2.0
There's a pretty good thread for that where they explain basic settings to more advanced settings to migrate from JSF 1.2 to JSF 2.0
Problems with migration from JSF 1.2 to 2.0
You're using JSPX instead of Facelets. This is not going to work flawlessly on JSF 2.0. If upgrading to JSF 2.1 where JSPX is been supported is not an option, then you need to rename your .jspx
files to .xhtml
and remove the now superfluous xmlns:jsp
taglib declaration. Remove also that javax.faces.DEFAULT_SUFFIX
context param which defaults to .xhtml
already.
What is the best strategy to update web project from JSF 1.1 to JSF 2.x?
To answer my own question: After working on this upgrade for some time and running into a few dead ends, for me the following order of steps has turned out best:
- Upgrade JSF implementation (in my case: from MyFaces 1.1 to MyFaces 2.2.12)
- Replace JSP files with Facelets and comment out all occurences of tags from unsupported tag libraries (some functionality will be lost until the migration is completed, but this way I have to migrate those taglibs just once - to use them in Facelets - and not twice (once for use in JSPs with JSF 2, and then for use in Facelets))
- Replace and update unsupported and outdated tag libs
Related Topics
How to Get the Download Url from Firebase Storage
Update Eclipse With Android Development Tools V. 23
Where to Store Application Data (Non-User Specific) on Linux
How to Set a Custom Font For Entire of Application
Android 6.0 Multiple Permissions
Launching Google Maps Directions Via an Intent on Android
Android Update 17 Seems Incompatible With External Jars
How to Parse Json Array (Not Json Object) in Android
Java.Text.Parseexception: Unparseable Date: Java.Text.Dateformat.Parse(Dateformat.Java:579)
After Google Play Service Update to Version 13 I Got an Error
How to Return a Boolean from Asynctask
Android: How to Use Alarmmanager
Sqlite Getting Nearest Locations (With Latitude and Longitude)
Generating All Permutations of a Given String
Error: Could Not Find or Load Main Class