Wildfly
upgrade for Java Server Faces
applications
Background
This document describes the basic
changes for migrating JSF 2 applications from Wildfly v20 (JBOSS
Enterprise Application Platform 7) to v30+ (or JBOSS EAP 8) – for
version mapping between Wildfly and Jboss EAP, please refer to
Appendix. The main changes in the later versions of Wildfly/Jboss EAP
are package rename and deprecation. For example, the old
javax.faces.* packages are renamed to jakarta.faces.*. This will need
the Java library dependency changes and the reference updates in the
application source code. Also some changes are required in the
application configuration and web application deployment descriptors
(eg web.xml).
Preparation
Download and install Wildfly 35,
WildFly
Downloads
Configure the application server
supporting libraries if needed. Like the previous application server,
ojdbc libraries may need to be copied to the application server,
%JBOSS_HOME%\modules\system\layers\base.
Set up admin account (use
%JBOSS_HOME%\bin\add-user.bat) for accessing the Wildfly/Jboss EAP
admin console: http://localhost:9990
Basic Changes
Here are the general steps:
replace the library references
in project configuration file (eg pom.xml in Apache Maven)
update the references in the
source code based on the new libraries. If
no new libraries to use, may need to consider to rewrite certain
application functions.
compile and package the
application and fix any compile errors
deploy the application package
to the running application server and fix any deployment errors
test the application and fix the
runtime errors
Maven project file,
pom.xml
Name
|
Old Library (to be replaced)
|
New Library
|
jUnit
|
3.x
|
4.x
|
JAXB API
|
javax.xml.bind > jaxb-api
|
jakarta.xml.bind
> jakarta.xml.bind-api
|
JSF API
|
com.sun.faces > jsf-api
|
jakarta.platform > jakarta.jakartaee-api
or jakarta.faces
> jakarta.faces-api
|
JSF IMPL
|
com.sun.faces > jsf-api
|
CDI Support
|
|
jakarta.enterprise > jakarta.enterprise.cdi-api
|
Java Servlet
|
javax.servlet > javax.servlet-api
|
jakarta.servlet > jakarta.servlet-api
|
Expression Language
|
javax.el > javax.el-api
|
jakarta.el > jakarta.el-api
|
JSTL (taglib)
|
javax.servlet.jsp.jstl > jstl-api
|
jakarta.servlet.jsp.jstl > jakarta.servlet.jsp.jstl-api
|
JEE API
|
Javax > javaee-api
|
(upgrade the version only if needed)
|
JMS
|
(the libs with JEE API may not work)
|
jakarta.jms > jakarta.jms-api
|
RESTful WS API
|
javax.ws.rs > javax.ws.rs-api
|
jakarta.ws.rs > jakarta.ws.rs-api
|
OJDBC
|
com.oracle > ojdbc
|
(upgrade the version only if needed)
|
Hibernate
|
org.hibernate > hibernate-core
|
org.hibernate.orm > hibernate-core
|
Plugins update with new versions
|
org.apache.maven.plugins > maven-compiler-plugin
|
org.apache.maven.plugins > maven-resources-plugin
|
org.apache.maven.plugins > maven-war-plugin
|
Package reference rename in application source code
The
following list contains the new references:
import
jakarta.annotation.PostConstruct;
import
jakarta.el.ELResolver;
import
jakarta.enterprise.context.ApplicationScoped;
import
jakarta.enterprise.context.RequestScoped;
import
jakarta.enterprise.context.SessionScoped;
import
jakarta.enterprise.inject.Disposes;
import
jakarta.enterprise.inject.Produces;
import
jakarta.faces.application.FacesMessage;
import
jakarta.faces.context.FacesContext;
import
jakarta.faces.event.AjaxBehaviorEvent;
import
jakarta.faces.event.PhaseEvent;
import
jakarta.faces.event.PhaseId;
import
jakarta.faces.event.PhaseListener;
import
jakarta.faces.model.SelectItem;
import
jakarta.inject.Inject;
import
jakarta.inject.Named;
import
jakarta.jms.BytesMessage;
import
jakarta.jms.Queue;
import
jakarta.jms.QueueConnection;
import
jakarta.jms.QueueConnectionFactory;
import
jakarta.jms.QueueSender;
import
jakarta.jms.QueueSession;
import
jakarta.persistence.CascadeType;
import
jakarta.persistence.Column;
import
jakarta.persistence.ElementCollection;
import
jakarta.persistence.Entity;
import
jakarta.persistence.EntityManager;
import
jakarta.persistence.EntityManagerFactory;
import
jakarta.persistence.EntityTransaction;
import
jakarta.persistence.FetchType;
import
jakarta.persistence.Id;
import
jakarta.persistence.JoinColumn;
import
jakarta.persistence.JoinTable;
import
jakarta.persistence.ManyToMany;
import
jakarta.persistence.MapKeyColumn;
import
jakarta.persistence.NamedQueries;
import
jakarta.persistence.NamedQuery;
import
jakarta.persistence.OrderBy;
import
jakarta.persistence.Table;
import
jakarta.persistence.Transient;
import
jakarta.servlet.http.HttpServletRequest;
import
jakarta.servlet.http.HttpServletResponse;
import
jakarta.servlet.http.HttpSession;
import
jakarta.ws.rs.client.Client;
import
jakarta.ws.rs.client.ClientBuilder;
import
jakarta.ws.rs.client.Entity;
import
jakarta.ws.rs.client.WebTarget;
import
jakarta.ws.rs.Consumes;
import
jakarta.ws.rs.core.Context;
import
jakarta.ws.rs.core.MediaType;
import
jakarta.ws.rs.core.Response;
import
jakarta.ws.rs.core.UriInfo;
import
jakarta.ws.rs.DELETE;
import
jakarta.ws.rs.ext.ParamConverter;
import
jakarta.ws.rs.ext.Provider;
import
jakarta.ws.rs.GET;
import
jakarta.ws.rs.HeaderParam;
import
jakarta.ws.rs.Path;
import
jakarta.ws.rs.PathParam;
import
jakarta.ws.rs.POST;
import
jakarta.ws.rs.Produces;
import
jakarta.ws.rs.PUT;
import
jakarta.ws.rs.QueryParam;
import
jakarta.jms.BytesMessage;
import
jakarta.jms.Queue;
import
jakarta.jms.QueueConnection;
import
jakarta.jms.QueueConnectionFactory;
import
jakarta.jms.QueueSender;
import
jakarta.jms.QueueSession;
find the
old class types defined there and rename if available. For example of
the following new names:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<error-page>
<exception-type>jakarta.faces.application.ViewExpiredException</exception-type>
<location>/m_login.xhtml</location>
</error-page>
@NamedQuery with implicit
‘SELECT’ not allowed, so add “SELECT <object alias> ”
before “FROM”
@Type(type = "yes_no")
replaced by @Convert(converter = YesNoConverter.class). Note: when
referring to it in NativeQueries, you may need to pass a true/false
query parameter instead of hard-coded Y/N in the query.
@Singlton may need to be
replaced with @ApplicationScoped because the @PostConstructed method
in @Singlton may not be executed.
Potential Issues
Some old 3rd party libraries (eg Richfaces) may be
out-of-support with using the old packages, and they will need to be
replaced with the similar well-supported/updated libraries. For
example, if the JSF applications are using Richfaces (UI components
or AJAX), consider to replace with PrimeFaces for example. For
possible Richfaces component replacements, refer to Appendix.
Appendix
Version Mapping between JBoss
EAP and Wildfly
JBoss EAP Version
|
WildFly Version
|
8
|
28
|
7.4
|
23
|
7.3
|
18
|
7.2
|
14
|
7.1
|
11
|
7
|
10
|
Richfaces to Primefaces
Migration References
|
RichFaces (change from)
|
PrimeFaces (change to)
|
|
Listener
|
a4j:actionListener
|
f:setPropertyActionListener
|
AJAX
|
a4j:ajax
|
p:ajax
|
Button
|
a4j:commandButton render
|
p:commandButton update=
|
Link
|
a4j:commandLink
|
p:commandLink
|
JS function
|
a4j:jsFunction
|
p:remoteCommand
|
Media output
|
a4j:mediaOutput
|
p:graphicImage, ...
|
Output area
|
a4j:outputPanel
|
div or p:tab or p:outputPanel
|
Parameter
|
a4j:param
|
f:param
|
Region
|
a4j:region
|
h:panelGroup or p:fragment
|
Repeat
|
a4j:repeat
|
p:repeat
|
Status
|
a4j:status
|
p:ajaxStatus
|
Accordion
|
rich:accordion
|
p:accordionPanel
|
Accord. item
|
rich:accordionItem
|
p:tab
|
Autocomplete
|
rich:autocomplete
|
p:autocomplete
|
Calendar
|
rich:calendar
|
p:calendar
|
Sub-table
|
rich:collapsibleSubTable
|
p:dataTable (nested)
|
Column
|
rich:column
|
p:column
|
Button
|
rich:commandButton
|
p:commandButton ajax="false"
|
Command link
|
rich:commandLink
|
p:commandLink ajax="false"
|
Control
|
rich:componentControl
|
JS function
|
Data grid
|
rich:dataGrid
|
p:dataGrid
|
Data scroll
|
rich:dataScroller
|
remove (use paginator)
|
Data table
|
rich:dataTable
|
p:dataTable
|
Sub-menu
|
rich:dropDownMenu
|
p:submenu
|
Editor
|
rich:editor
|
p:editor(p:textEditor in PF 6)
|
File upload
|
rich:fileUpload
|
p:fileUpload
|
Focus
|
rich:focus
|
p:focus
|
Google map
|
rich:gmap (RF3)
|
p:gmap
|
Hot key
|
rich:hotKey
|
p:hotkey
|
Spinner
|
rich:inputNumberSpinner
|
p:spinner
|
List
|
rich:list
|
p:dataList
|
Menu item
|
rich:menuItem
|
p:menuitem
|
Message
|
rich:message
|
p:message
|
Messages
|
rich:messages
|
p:messages
|
Panel
|
rich:panel
|
p:panel
|
Panel menu
|
rich:panelMenu
|
p:panelMenu or p:menu
|
Menu item
|
rich:panelMenuItem
|
p:menuitem
|
Pick list
|
rich:pickList
|
p:pickList
|
Popup
|
rich:popup
|
p:dialog
|
Select one
|
rich:select
|
p:selectOneMenu
|
Tab
|
rich:tab
|
p:tab
|
Menu bar
|
rich:toolbar
|
p:menubar or p:toolbar
|
Menu group
|
rich:toolbarGroup
|
remove
|
Tooltip
|
rich:tooltip
|
p:tooltip
|
Tree
|
rich:tree
|
p:tree
|
Tree node
|
rich:treeNode
|
p:treeNode
|
Label
|
h:outputLabel
|
p:outputLabel
|
Input text
|
h:inputText
|
p:inputText
|
Input secret
|
h:inputSecret
|
p:password
|
Message
|
h:message
|
p:message
|
Messages
|
h:messages
|
p:messages
|
Text area
|
h:inputTextarea
|
p:inputTextarea
|
Dropdown
|
h:selectOneListbox
|
p:selectOneMenu
|
Select one
|
h:selectOneMenu
|
p:selectOneMenu
|
Multi-select
|
h:selectManyListbox
|
p:selectManyMenu
|
Check box
|
h:selectBooleanCheckbox
|
p:selectBooleanCheckbox
|
Check boxes
|
h:selectManyCheckbox
|
p:selectManyCheckbox
|
Radio button
|
h:selectOneRadio
|
p:selectOneRadio
|
Button
|
h:commandButton
|
p:commandButton ajax="false
|
Regular link
|
h:commandLink
|
p:commandLink ajax="false"
|
Image link
|
h:commandLink
|
p:menuitem
|
Link
|
h:link
|
p:link
|
Column
|
h:column
|
p:column
|
Repeat
|
ui:repeat
|
p:repeat
|
Field set
|
fieldset
|
p:fieldset
|
References
Migration
Guide 3.0: Hibernate ORM 5 to 6 migration · quarkusio/quarkus Wiki
Getting
Started With Jakarta EE 10 - Jakarta CDI
Alternative
of richfaces components in primefaces - Stack Overflow