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
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
Update the library dependencies as the following. Find updated 3rd party library dependencies from Maven Repository: Search/Browse/Explore. For the new versions, look at what’s bundled with the wildfly. Eg in %JBOSS_HOME%\modules\system\layers\base\*
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 |
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
Change imports with the new package names from the above new libraries
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;
Update WEB-INF\web.xml
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”
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