Versions & Implementations
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against Jakarta Faces 4.1 (Jakarta EE 11, API artifact jakarta.faces-api 4.1.2, Java SE 17 or
later), Eclipse Mojarra 4.1.17 and Apache MyFaces Core 4.1.4, with Java 21 for the examples. The versions were checked
on 2026-10-08 against Maven Central, the Jakarta EE specification pages and the project sites. Jakarta Faces 4.0
(Jakarta EE 10, Java SE 11 or later; Mojarra 4.0.26, MyFaces 4.0.4) is still widely deployed, so every section says
where 4.0 behaves differently. Jakarta Faces 5.0 (Jakarta EE 12, Java SE 21 or later) is under development: the latest
milestone of the API is 5.0.0-M9 (2026-09-18) and everything said about it here is described as upcoming, never as
current behaviour. The examples belong to the running Bookshelf scenario of this section — a catalogue of books,
authors and reviews — and were compiled in a scratch Maven project on JDK 26 with --release 21.
Specification versus implementation
Jakarta Faces is a specification: a document, an API, a tag library description and a technology compatibility kit
(TCK) published by the Eclipse Foundation under the Jakarta EE Specification Process. The 4.1 specification page links
the specification document, the Javadoc, the JavaScript documentation, the render kit documentation, the tag
documentation (VDLDoc) and the TCK, and lists the Maven coordinates jakarta.faces:jakarta.faces-api as the API
artifact. An implementation is a separate product that passes the TCK and is then listed as a compatible
implementation. Two implementations are in production use:
-
Eclipse Mojarra, the former reference implementation, developed in the Eclipse EE4J project. Eclipse GlassFish is the compatible platform that the 4.1 specification page lists next to Mojarra.
-
Apache MyFaces Core, the Apache Software Foundation implementation, which also ships inside several other products and has its own site and configuration reference.
The practical consequences are these. Application code compiles against the API only, so the dependency on
jakarta.faces-api has scope provided when the server brings its own implementation. A server that does not
(Tomcat, a plain Servlet container, an embedded runtime) needs an implementation in the WAR. Anything implementation
specific — context parameters in the com.sun.faces or org.apache.myfaces namespace, internal classes, default
values that the specification leaves open — is a portability risk and is covered in the next section.
document, API, VDLDoc, JavaScript docs"] api["jakarta.faces-api 4.1.2
compile against this"] tck["Faces TCK"] moj["Eclipse Mojarra 4.1.x
org.glassfish:jakarta.faces"] myf["Apache MyFaces Core 4.1.x
myfaces-api + myfaces-impl"] web["Jakarta EE 11 Web Profile"] plat["Jakarta EE 11 Platform"] core["Jakarta EE 11 Core Profile
no Faces"] srv["Servers: GlassFish, Payara, WildFly, Open Liberty ..."] lib["PrimeFaces 16, OmniFaces 5
run on any compatible implementation"] spec --> api spec --> tck tck -. "certifies" .-> moj tck -. "certifies" .-> myf api -. "implemented by" .-> moj api -. "implemented by" .-> myf web --> spec plat --> web srv --> plat srv --> moj lib --> api core -. "does not include" .-> spec
The Maven snippets below show the three ways to put Faces on the class path of the Bookshelf WAR. The first is for a
Jakarta EE server: nothing is packaged. The other two package an implementation. The Mojarra artifact
org.glassfish:jakarta.faces already contains the API classes, so with Mojarra the provided API dependency is
only needed to compile against a specific API version when the server supplies the runtime; the MyFaces
implementation artifact pulls its API artifact myfaces-api in transitively, and the API comes from MyFaces itself
rather than from jakarta.faces-api. All three variants were built with mvn package in the scratch project.
<!-- A: Jakarta EE 11 server (GlassFish 8, Payara 7, WildFly 40 or later ...): API only, provided by the server -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>11.0.0</version>
<scope>provided</scope>
</dependency>
<!-- B: Tomcat 11 or a Servlet container, with Eclipse Mojarra 4.1.x -->
<dependency>
<groupId>jakarta.faces</groupId>
<artifactId>jakarta.faces-api</artifactId>
<version>4.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.faces</artifactId>
<version>4.1.17</version>
</dependency>
<!-- C: Tomcat 11 or a Servlet container, with Apache MyFaces Core 4.1.x (use A or the Servlet API for the rest) -->
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>4.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>4.1.4</version>
</dependency>
A real project uses one of the three blocks, not all of them. Variant B is the one the Tomcat and Weld page of this
section builds on, and variant C appears again on the Spring Boot with JoinFaces and Quarkus pages, where MyFaces is a common
choice. The jakartaee-web-api artifact (the Web Profile) is enough for a Faces application; the full
jakarta.jakartaee-api is only needed if the code also uses Platform-only specifications.
Eclipse Mojarra versus Apache MyFaces
Both implementations pass the Faces TCK, so a portable application behaves the same on either. The differences are in what surrounds the specification.
| Aspect | Eclipse Mojarra | Apache MyFaces Core |
|---|---|---|
Latest 4.1 and 4.0 releases |
4.1.17 and 4.0.26 |
4.1.4 and 4.0.4 |
Maven coordinates |
|
|
Java baseline per the project docs |
4.0 needs Java 11, 3.0 and 2.3 need Java 8 |
4.1 needs Java 17, 4.0 needs Java 11, 3.0 and 2.3 need Java 8 |
Servlet, EL, CDI required (4.1) |
as required by Faces 4.1 |
Servlet 6.1 or later, EL 6.0, CDI 4.1; JSTL 3.0 and Bean Validation 3.1 are optional |
Support policy |
The site states that Eclipse does not support Faces 2.2 and lower |
The 2.0, 2.1 and 2.2 lines are documented as old versions |
Own configuration namespace |
|
|
Documentation of its parameters |
The source of the configuration class |
A reference table on the 4.1 page of the site, with "since" and default columns |
Development lines |
4.1.x and 4.0.x are both patched; master is Faces 5.0 |
4.1.x and 4.0.x; a 5.0 line is announced as "in development, not yet released" |
MyFaces 4.0 is a new code base. The MyFaces 4.0 page says that it is based on the 2.3-next branch and is a completely new code base compared with 3.0 and 2.3: shared modules and dependencies were removed, the size is about 1 MB smaller, it has no dependencies, it is said to be up to 15% faster when the lambda meta factory is enabled, the JavaScript was rewritten in TypeScript and the default parameters were tuned for usability and performance.
Release cadence. Counting the versions published on Maven Central, Mojarra published seventeen 4.1 releases (4.1.1 on 2024-06-25 up to 4.1.17 on 2026-09-18) and patched the 4.0 line to 4.0.26 in the same period, which is roughly one release every seven weeks. MyFaces published five 4.1 releases (4.1.0 on 2024-12-04 up to 4.1.4 in September 2026), a slower rhythm. Both lines receive fixes after a new minor version appears, so staying on the latest patch of the line you use is the normal upgrade path. Faces 4.1 itself was ratified on 2024-06-04, six months before MyFaces 4.1.0; the specification page lists Mojarra 4.1.1 and the two GlassFish 8 milestones as the implementations that certified it.
Context parameters. Parameters whose names start with jakarta.faces. are defined by the specification and are
read by both implementations; examples are jakarta.faces.PROJECT_STAGE, jakarta.faces.FACELETS_REFRESH_PERIOD,
jakarta.faces.STATE_SAVING_METHOD and jakarta.faces.ENABLE_WEBSOCKET_ENDPOINT. Names that start with
com.sun.faces. belong to Mojarra and names that start with org.apache.myfaces. belong to MyFaces. The defaults
differ, which matters when an application moves from one to the other.
| Purpose | Mojarra (default) | MyFaces (default) |
|---|---|---|
Views remembered per session with server state saving |
|
|
Compress the serialized state |
|
|
Encrypt the client-side view state |
not compared here; see the configuration class linked below |
|
Early flush of the head element |
no equivalent compared here |
|
Reflection versus lambda accessors |
not applicable |
|
Threaded view building |
|
not applicable |
An implementation reads only its own parameters, so the example below configures the same intent for both. Replace the values with the numbers your own load test justifies; keeping fewer remembered views reduces the memory used by server state saving per session, at the price of the browser’s Back button failing earlier.
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_1.xsd"
version="6.1">
<!-- defined by the specification: read by Mojarra and MyFaces -->
<context-param>
<param-name>jakarta.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!-- Mojarra only -->
<context-param>
<param-name>com.sun.faces.numberOfViewsInSession</param-name>
<param-value>10</param-value>
</context-param>
<!-- MyFaces only -->
<context-param>
<param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
<param-value>10</param-value>
</context-param>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
Telling the two apart at run time. A page or a log line that reports the implementation helps when a bug report must
name it. The bean below decides from the package of the Application object and reads the API version from the
manifest of the API jar; the view prints both.
package org.example.bookshelf.web;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Named;
@Named
@RequestScoped
public class RuntimeInfoBean {
public String getImplementation() {
String applicationClass = FacesContext.getCurrentInstance().getApplication().getClass().getName();
if (applicationClass.startsWith("com.sun.faces.")) {
return "Eclipse Mojarra";
}
if (applicationClass.startsWith("org.apache.myfaces.")) {
return "Apache MyFaces";
}
return "Unknown (" + applicationClass + ")";
}
public String getApiVersion() {
String version = FacesContext.class.getPackage().getImplementationVersion();
return version != null ? version : "not declared";
}
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html">
<h:head><title>Bookshelf runtime</title></h:head>
<h:body>
<p>Implementation: <h:outputText value="#{runtimeInfoBean.implementation}"/></p>
<p>API version: <h:outputText value="#{runtimeInfoBean.apiVersion}"/></p>
</h:body>
</html>
Jakarta EE profiles and where Faces sits
Jakarta EE is published as three specifications that list what a compatible product must provide: the Platform, the Web Profile (a subset aimed at web applications) and the Core Profile (a much smaller subset for microservice runtimes). Faces belongs to the first two.
-
The Jakarta EE 11 Web Profile specification lists Jakarta Faces 4.1 among its required specifications. Its introduction describes the profile as a complete web stack with presentation and state management (Faces and Pages), Servlet, Enterprise Beans Lite, and so on.
-
The Jakarta EE 11 Platform contains the Web Profile specifications and more; its specification has a chapter on the requirements for Faces 4.1.
-
The Jakarta EE 11 Core Profile does not include Faces. Its release notes list updates of Annotations, Interceptors, CDI and RESTful Web Services only, and its specification text does not mention Faces. A Core Profile runtime such as a MicroProfile server therefore needs Faces added as a library or as a server feature.
The same relationship holds one release earlier: Jakarta EE 10 includes Jakarta Faces 4.0 in the Platform and in the Web Profile. For Jakarta EE 12 the Platform and Web Profile pages announce the update "Jakarta Faces 4.1 to 5.0" and a minimum of Java SE 21; that release is still being planned.
| Jakarta EE | Faces | Profiles with Faces | Core Profile has Faces | Minimum Java SE of the release |
|---|---|---|---|---|
8 |
2.3 |
Platform, Web Profile |
not applicable |
Java 8 (the requirement of Mojarra and MyFaces 2.3) |
9 and 9.1 |
3.0 |
Platform, Web Profile |
not applicable |
Java 8 (Mojarra and MyFaces 3.0); the 9.1 compatibility list shows builds certified on Java 8 and on Java 11 |
10 |
4.0 |
Platform, Web Profile |
no |
Java SE 11 |
11 |
4.1 |
Platform, Web Profile |
no |
Java SE 17 |
12 (planned) |
5.0 |
Platform, Web Profile |
not decided here |
Java SE 21 |
What this means for a project. If the target is "any Jakarta EE 11 Web Profile server", declare
jakarta.jakartaee-web-api as provided and write only standard Faces. If the target is Tomcat or a Core Profile
runtime, package an implementation as in variants B or C above, and remember that CDI, Expression Language and
Bean Validation have to be present as well; the Tomcat and Weld page of this section does that. The
Jakarta EE servers page covers the servers one by one.
The Java baseline of each version
Each Faces release raised the minimum Java version together with its Jakarta EE release. The 4.0 and later values are printed on the specification pages as "Minimum Java SE Version"; for the older versions the table uses the requirements published by the implementations, because the specification pages of 2.x do not state one.
| Faces | Java SE | Source of the number |
|---|---|---|
2.0 and 2.1 |
5 |
MyFaces 2.0 and 2.1 requirements (Java 1.5) |
2.2 |
6 |
MyFaces 2.2 requirements (Java 1.6) |
2.3 |
8 |
MyFaces 2.3 and the Mojarra site |
3.0 |
8 |
MyFaces 3.0 and the Mojarra site |
4.0 |
11 |
Faces 4.0 specification page and the change log (aligned with Jakarta EE 10) |
4.1 |
17 |
Faces 4.1 specification page and its change log (aligned with Jakarta EE 11) |
5.0 (upcoming) |
21 |
Faces 5.0 specification page (Java SE 21 or higher) |
Two details are easy to get wrong. First, running on a newer JDK than the minimum is normal — the examples of this
section use Java 21 and compile with JDK 26 — but the minimum decides which language features the API may use:
Faces 4.1 requires Java 17, so records are fine in beans and jakarta.faces.view.ViewScoped beans may be written as
classes that use List.of. Second, the application server may demand more than Faces: MyFaces 4.1 lists Servlet 6.1,
EL 6.0 and CDI 4.1 as requirements, which is why it needs a Servlet container of the Tomcat 11 generation.
Source: Jakarta Faces 4.1 — minimum Java SE version, Jakarta Faces 4.0, Jakarta Faces 5.0 and the MyFaces 2.2 and 2.3 version pages
The version matrix
The matrix joins the specification line to the libraries and servers around it. The Faces, Jakarta EE and Java columns come from the specification pages. The implementation columns give the last line of each project as published on Maven Central. The server column lists the products that the Jakarta EE site shows as certified for that release.
| Faces | Jakarta EE | Java SE | Mojarra and MyFaces | OmniFaces (Faces / Java) | Certified servers (jakarta.ee) |
|---|---|---|---|---|---|
2.3 |
8 |
8 |
Mojarra 2.3.21, MyFaces 2.3.12 |
3.x (2.3 / Java 8), latest 3.14.26 |
Eclipse GlassFish 5.1 |
3.0 |
9 and 9.1 |
8 (9.1 also 11) |
Mojarra 3.0.5, MyFaces 3.0.4 |
4.x (3.0 and 4.0 / Java 11), latest 4.7.15 |
GlassFish 6.0 and 6.1, WildFly Preview 23, Open Liberty beta |
4.0 |
10 |
11 |
Mojarra 4.0.26, MyFaces 4.0.4 |
4.x (3.0 and 4.0 / Java 11), latest 4.7.15 |
GlassFish 7, WildFly 33, Open Liberty, Payara 6 |
4.1 |
11 |
17 |
Mojarra 4.1.17, MyFaces 4.1.4 |
5.x (4.1 and 5.0 / Java 17), latest 5.5.5 |
GlassFish 8, Payara 7, Open Liberty 26.0.0.5 (Platform and Web Profile); WildFly 40 added Jakarta EE 11 support |
5.0 (upcoming) |
12 (planned) |
21 |
Mojarra 5.0.0 milestones; MyFaces 5.0 not released |
OmniFaces 5.x lists 5.0 as its upper Faces version |
none yet |
PrimeFaces. One jar serves several Faces versions. PrimeFaces 16.0.0 (2026-09-04) is documented as requiring a Java 11
or later runtime and a Faces implementation, and its Maven download page offers the single artifact
org.primefaces:primefaces for "Jakarta Faces (4.0 - 5.0, jakarta namespace)". The 15.x line (15.0.18) is the previous
one. The PrimeFaces dependency page still lists older Faces versions in a table, so treat the download page as the
statement for the jakarta line. PrimeFaces Extensions has a matching 16.0.0.
Servers. The Jakarta EE site lists, for the Jakarta EE 11 Platform, Eclipse GlassFish 8.0.0-M12, Azul Payara 7.0.0 and
Payara Community 7.2026.5, and Open Liberty 26.0.0.5; for the Web Profile, GlassFish, Payara and Open Liberty; and
for the Core Profile, WildFly 34 and Open Liberty. The WildFly project announced that its 40 release delivers
Jakarta EE 11 support. Apache TomEE 10.2.0 implements Jakarta EE 10 and the TomEE 11 download is a 11.0.0-M1 milestone
for Jakarta EE 11. Tomcat is a Servlet container and not a Jakarta EE product: Faces on Tomcat means packaging an
implementation, CDI (Weld) and Expression Language, as in variants B and C above. At the time of writing the
current GlassFish is 8.0.5, WildFly 41.0.1.Final, Payara 7.2026.9 and Open Liberty 26.0.0.10 with the faces-4.1
feature; the certification lists above name earlier builds because they are the ones submitted for certification.
What is new, deprecated and removed in each version
The appendix "Change Log" of the specification lists every issue per release, back to 2.0. The summaries below keep what matters to a Bookshelf developer. Each version has one short example, written with current names, for a feature that first appeared in that version.
Faces 2.0 (JSR 314, Java EE 6)
Faces 2.0 changed how applications are built, and it is the version that the older books describe most. It made
Facelets the standard view declaration language, so XHTML views replaced JSP views. It introduced composite components,
built-in Ajax with f:ajax and the JavaScript API, a resource handling mechanism for scripts, style sheets and images,
system events, view parameters and bookmarkable URLs, implicit navigation, the project stage, annotations such as the
component and converter registrations, and the integration with Bean Validation. Its own managed bean facility
(javax.faces.bean) was part of 2.0. It is also the release behind most of the instructions of the 2.0 era books, which
the section on outdated material below explains.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:f="jakarta.faces.core"
xmlns:ui="jakarta.faces.facelets">
<h:head><title>Catalogue</title></h:head>
<h:body>
<h:form id="search">
<h:inputText id="q" value="#{catalogue.query}">
<f:ajax event="keyup" listener="#{catalogue.search}" render="results"/>
</h:inputText>
<h:panelGroup id="results" layout="block">
<ui:repeat value="#{catalogue.results}" var="title">
<p>#{title}</p>
</ui:repeat>
</h:panelGroup>
</h:form>
</h:body>
</html>
package org.example.bookshelf.web;
import jakarta.faces.event.AjaxBehaviorEvent;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import java.io.Serializable;
import java.util.List;
@Named("catalogue")
@ViewScoped
public class CatalogueBean implements Serializable {
private static final List<String> TITLES = List.of("Dune", "Neuromancer", "Solaris", "Hyperion");
private String query = "";
private List<String> results = TITLES;
public String getQuery() { return query; }
public void setQuery(String query) { this.query = query; }
public List<String> getResults() { return results; }
public void search(AjaxBehaviorEvent event) {
String needle = query == null ? "" : query.toLowerCase();
results = TITLES.stream().filter(t -> t.toLowerCase().contains(needle)).toList();
}
}
Faces 2.1
Faces 2.1 was a small release: the change log records the facelets-processing element, the
facelet-cache-factory element in the configuration schema, and a change to the Restore View phase that calls
ViewHandler.deriveLogicalViewId() before locating the view declaration language. Nothing in an application usually
changes between 2.0 and 2.1, which is why many projects say "2.x" for both. The example is the Restore View entry point
that you can observe with a phase listener; the lifecycle page of this section explains the phases.
package org.example.bookshelf.web;
import jakarta.faces.event.PhaseEvent;
import jakarta.faces.event.PhaseId;
import jakarta.faces.event.PhaseListener;
import java.util.logging.Logger;
public class RestoreViewLogger implements PhaseListener {
private static final Logger LOG = Logger.getLogger(RestoreViewLogger.class.getName());
@Override
public void beforePhase(PhaseEvent event) {
LOG.fine(() -> "entering " + event.getPhaseId());
}
@Override
public void afterPhase(PhaseEvent event) { }
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
<faces-config xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_4_1.xsd"
version="4.1">
<lifecycle>
<phase-listener>org.example.bookshelf.web.RestoreViewLogger</phase-listener>
</lifecycle>
</faces-config>
Faces 2.2 (JSR 344, Java EE 7)
The change log lists four big-ticket features: HTML5 friendly markup (passthrough attributes and elements), resource
library contracts, Faces Flows and stateless views. Alongside them 2.2 added the UIViewAction component (the
f:viewAction tag, first from the Seam Faces module), the ClientWindow abstraction for browser tabs and windows, file
upload with h:inputFile, the CDI @ViewScoped annotation in jakarta.faces.view (the successor of the managed bean
view scope), @FlowScoped, protected views, FlashFactory, the transient attribute on f:view for stateless views,
and a new XML namespace (http://xmlns.jcp.org/jsf/...) for the tag libraries. The release deprecated StateManager in
favour of StateManagementStrategy, deprecated the CURRENT_COMPONENT attributes and announced that
javax.faces.bean would be deprecated in the next version.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:f="jakarta.faces.core">
<f:metadata>
<f:viewParam name="id" value="#{bookDetails.id}" required="true"/>
<f:viewAction action="#{bookDetails.load}"/>
</f:metadata>
<h:head><title>Book</title></h:head>
<h:body>
<h1>#{bookDetails.title}</h1>
</h:body>
</html>
package org.example.bookshelf.web;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import java.io.Serializable;
@Named("bookDetails")
@ViewScoped
public class BookDetailsBean implements Serializable {
private Long id;
private String title;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
/** Runs after the view parameters were applied and validated. */
public void load() {
title = "Book #" + id;
}
}
package org.example.bookshelf.web;
import jakarta.faces.flow.FlowScoped;
import jakarta.inject.Named;
import java.io.Serializable;
/** State of the borrow wizard; lives while the flow with id "borrow" is active. */
@Named
@FlowScoped("borrow")
public class BorrowFlowBean implements Serializable {
private String reader;
public String getReader() { return reader; }
public void setReader(String reader) { this.reader = reader; }
}
Faces 2.3 (JSR 372, Java EE 8)
Faces 2.3 is the version in which Faces became a full CDI citizen. The change log lists WebSocket integration
(f:websocket and the CDI @Push annotation), multi-field validation with f:validateWholeBean, java.time support
in f:convertDateTime, the use of CDI to evaluate the Faces specific implicit objects in expressions, @Inject on
Faces artefacts (converters, validators and others become injectable), the CDI replacement for @ManagedProperty
(ManagedProperty in the annotation package, used together with @Inject), UIData and ui:repeat over Map and
Iterable, registerable DataModel implementations (FacesDataModel), h:commandScript, an enhanced component search
facility (the search expressions used by f:ajax execute and render), f:importConstants, and the
@FacesConfig annotation that activates the CDI-based features. It also deprecated javax.faces.bean, the managed
bean facility of 2.0. Backward compatibility is preserved unless a CDI bean carries @FacesConfig or one of three
named context parameters is set.
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" version="6.1">
<context-param>
<param-name>jakarta.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name>
<param-value>true</param-value>
</context-param>
</web-app>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:f="jakarta.faces.core">
<h:head><title>Live reviews</title></h:head>
<h:body>
<f:websocket channel="reviews" onmessage="function(message) { console.log(message); }"/>
</h:body>
</html>
package org.example.bookshelf.web;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.faces.push.Push;
import jakarta.faces.push.PushContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
@Named
@ApplicationScoped
public class ReviewFeedBean {
@Inject
@Push(channel = "reviews")
private PushContext reviews;
public void announce(String summary) {
reviews.send(summary);
}
}
Faces 3.0 (Jakarta EE 9)
Faces 3.0 added no features. Its change log has one entry: the namespace changed from javax.faces to jakarta.faces.
That is a binary-breaking change for every import, every faces-config.xml and every library: PrimeFaces, OmniFaces
and any custom component have to be rebuilt against the new package names. The XML namespaces of the tag libraries
(http://xmlns.jcp.org/jsf/...) did not change in 3.0; they changed in 4.0. Jakarta EE 9.1 ran the same API on Java 11.
package org.example.bookshelf.web;
// Faces 2.3 and earlier (Java EE 8) imported javax.faces.view.ViewScoped and javax.inject.Named.
// Faces 3.0 and later (Jakarta EE 9 or later) import the jakarta packages:
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
@Named
@ViewScoped
public class ReviewFormBean implements java.io.Serializable {
private String text;
public String getText() { return text; }
public void setText(String text) { this.text = text; }
}
Faces 4.0 (Jakarta EE 10)
Faces 4.0 combined new features with a clean-up that removed everything that had been deprecated or superseded. The specification page and change log list the following.
-
New: an API to create Facelets programmatically; automatic extensionless mapping of the
FacesServlet;@ClientWindowScoped; custom cookie attributes such asSameSiteinExternalContext#addResponseCookie();multipleandacceptonh:inputFile;FacesContext#getLifecycle();f:selectItemGroupsandf:selectItemGroup; thetypeattribute ofh:inputText;UIViewRoot#getDoctype();onerroronf:websocket;layout="list"forh:selectManyCheckboxandh:selectOneRadio; annotation literals for all qualifiers; a more convenientUIComponent#subscribeToEvent(); omission of thetypeattribute oflinkandscriptwhen the doctype is HTML5; and betterf:ajaxbehaviour in composite components. -
Renamed: "JSF" became "Faces" everywhere, and the tag library namespaces changed from the
http://xmlns.jcp.org/jsf/...URLs to thejakarta.faces.*URNs (jakarta.faces.html,jakarta.faces.core,jakarta.faces.facelets,jakarta.faces.composite,jakarta.faces.passthrough), withjakarta.tags.corefor the Jakarta Standard Tag Library. -
Removed: all JSP support, the native managed beans (
@ManagedBeanand related),MethodBinding,ValueBindingand their relatives, theCURRENT_COMPONENTconstants ofUIComponent, the deprecated methods ofStateManager, and the wholeResourceResolverclass. Theversionelement of@FacesConfighas no effect any more and is deprecated for removal; the annotation itself still activates Faces and its CDI features. The JavaScript library file is the resourcefaces.jsof the libraryjakarta.faces, which replacedjsf.js. -
Baseline: Java SE 11, aligned with Jakarta EE 10.
@ClientWindowScoped, and the 4.0 namespaces in a viewpackage org.example.bookshelf.web;
import jakarta.faces.lifecycle.ClientWindowScoped;
import jakarta.inject.Named;
import java.io.Serializable;
@Named
@ClientWindowScoped
public class WizardWindowBean implements Serializable {
private String draft = "";
public String getDraft() { return draft; }
public void setDraft(String draft) { this.draft = draft; }
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:f="jakarta.faces.core"
xmlns:ui="jakarta.faces.facelets"
xmlns:cc="jakarta.faces.composite"
xmlns:pt="jakarta.faces.passthrough"
xmlns:c="jakarta.tags.core">
<h:head><title>Draft review</title></h:head>
<h:body>
<h:form>
<h:inputTextarea value="#{wizardWindowBean.draft}" pt:placeholder="Write your review"/>
<h:commandButton value="Save draft"/>
</h:form>
</h:body>
</html>
Faces 4.1 (Jakarta EE 11)
Faces 4.1 is a small release aligned with Jakarta EE 11. The specification page states that it removes references to the SecurityManager, aligns further with CDI and provides various small enhancements and clarifications.
-
New:
@Inject Flow currentFlowto inject the current flow;UUIDConverter; therowStatePreservedproperty ofUIRepeat, the same as inUIData; events for@Initialized,@BeforeDestroyedand@Destroyedof the built-in scopes; genericFacesMessage#VALUESandVALUES_MAP;ExternalContext.setResponseContentLengthLong;equals(),hashCode()andtoString()onFacesMessage; theifattribute off:viewActionin the VDL; and a default ofjakarta.faces.FACELETS_REFRESH_PERIODwhen the project stage is Development. -
Deprecated: full state saving,
PreDestroyCustomScopeEventandPostConstructCustomScopeEvent, andcomposite:extension. -
Removed: references to the SecurityManager.
-
Baseline: Java SE 17.
package org.example.bookshelf.web;
import jakarta.faces.flow.Flow;
import jakarta.faces.flow.FlowScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.io.Serializable;
@Named
@FlowScoped("borrow")
public class BorrowFlowInfoBean implements Serializable {
@Inject
private Flow currentFlow;
public String getFlowId() {
return currentFlow.getId();
}
}
Faces 5.0 (upcoming, Jakarta EE 12)
Faces 5.0 is not released. The specification page is marked as under development, sets the minimum at Java SE 21 and lists the planned work grouped by theme. Anything below can still change, and Mojarra 5.0 and MyFaces 5.0 are milestones or snapshots. Read the list as the direction of travel, and do not rely on it for a production design.
-
Planned features: Content Security Policy support (issue 590),
oninput-style HTML5 events forUIInput, and a newSUCCESSseverity forFacesMessage. Content Security Policy is not absent from the 4.x implementations meanwhile: Mojarra has had its own opt-in nonce support since 4.0.16, configured with the implementation parameterscom.sun.faces.enableCspNonce(a nonce per request, stamped on the scripts Mojarra renders) andcom.sun.faces.cspPolicy(the policy header, defaultscript-src 'self' 'nonce-#{nonce}' 'strict-dynamic'), and PrimeFaces offers its own CSP support. The 5.0 work standardises the idea underjakarta.facesnames, which Mojarra 4.1.17 does not read; the security page shows both. -
API modernisation: generics across converters, validators,
SelectItem,ValueChangeEvent,StateHelperand others; enums forPhaseIdand forFacesMessage.Severity; enums for context parameters that accept a fixed set of values. -
Removals and clean-up: removal of everything marked
@Deprecated(forRemoval = true, since = "4.0")(which includes theversionelement of@FacesConfig), removal ofcomposite:extensionand of the custom scope events, removal of the old XML namespaces, a possible deprecation ofprependIdonh:form, and splitting the API from the implementation code (step one). -
CDI, EL and Facelets: observing phase events with
@Observes, observable non-component Faces events,f:importConstantsallowed everywhere rather than only inf:metadata, and Expression Language 6.0OptionalandRecordresolvers in the resolver chain. -
Behaviour and specification fixes: a
clearModelattribute forf:resetValues, passthrough on facets, aplaceholderattribute forh:inputTextandh:inputTextarea, anHttpOnlyFlash cookie (issue 1201 on the 5.0 milestone, so a 5.0 item, not a 4.x change), and the documentation ofjakarta.faces.AUTOMATIC_EXTENSIONLESS_MAPPING.
For the platform, the Jakarta EE 12 pages announce Faces 4.1 to 5.0, Servlet 6.1 to 6.2 and, for Expression Language, the step from 6.0 to 6.1. To try a milestone in a scratch project without touching the production line, add it to a separate branch of the build and keep the 4.1 dependencies in the main one.
<dependency>
<groupId>jakarta.faces</groupId>
<artifactId>jakarta.faces-api</artifactId>
<version>5.0.0-M9</version>
<scope>provided</scope>
</dependency>
The changes at a glance
| Version | Added | Deprecated | Removed |
|---|---|---|---|
2.0 |
Facelets as the VDL, composite components, |
nothing |
|
2.1 |
small clarifications, |
nothing |
|
2.2 |
Faces Flows, |
|
nothing |
2.3 |
|
|
nothing |
3.0 |
nothing |
nothing |
|
4.0 |
programmatic Facelets, extensionless mapping, |
|
JSP, native managed beans, |
4.1 |
|
full state saving, |
SecurityManager references |
5.0 (upcoming) |
CSP support, generics and enums, |
candidate: |
planned: items deprecated for removal since 4.0, old XML namespaces |
Choosing a version in practice
-
New project, Jakarta EE 11 server or Tomcat 11: Faces 4.1 with Mojarra 4.1.x or MyFaces 4.1.x, Java 21, PrimeFaces 16 and OmniFaces 5.
-
Existing Jakarta EE 10 estate: Faces 4.0 with Mojarra 4.0.26 or MyFaces 4.0.4 and Java 11 or 17; OmniFaces 4.x is the matching line. Moving to 4.1 is mostly a Java 17 and server upgrade.
-
Still on
javax.faces(Faces 2.x, Java EE 8): the move tojakarta.facesis the big step; the migrating to Jakarta Faces page collects it. Go to 4.0 or 4.1 directly instead of stopping at 3.0. -
Faces 5.0: read the milestone notes (the migration page lists what is planned); do not plan production on it before the specification ballot completes.
See also Java, Web UI frameworks for Spring Boot and Starting a new project when the version decision is part of a wider technology choice, and Vaadin and Thymeleaf for the alternatives covered on this site.
Where the books are outdated
All eight books consulted for this section date from 2004 to 2015 and describe JSF 1.0 to 2.2 (and PrimeFaces 4 and 5). On versions and implementations they are outdated in these ways, and the official documentation wins in every case.
-
They name
javax.faceseverywhere; since 3.0 the package isjakarta.faces, and the tag library namespaces moved from thejava.sun.comandxmlns.jcp.orgURLs to thejakarta.faces.*URNs in 4.0. -
They show JSP views, JSP tag handlers and TLDs (and standalone Facelets 1.x with a custom
ViewHandler); Facelets has been built in since 2.0 and all JSP support was removed in 4.0. -
They use
@ManagedBeanand thejavax.faces.beanscopes; the facility was deprecated in 2.3 and removed in 4.0, replaced by CDI@Namedand thejakarta.enterprise.contextscopes plusjakarta.faces.view.ViewScoped. -
They know Sun’s reference implementation and Apache MyFaces 1.x/2.0; today the lines are Mojarra 4.1.x and MyFaces 4.1.x, MyFaces 4.0 is a rewritten code base, and Eclipse documents no support for Faces 2.2 and earlier.
-
They mention
jsf.js,MethodBinding,ValueBinding,ResourceResolverand deprecatedStateManagermethods;jsf.jsbecamefaces.jsand the others were removed in 4.0. -
They are silent on Faces Flows, CDI
@ViewScoped, passthrough markup, resource library contracts, stateless views,h:inputFile,f:viewAction,f:websocket, CDI injection,java.time, search expressions,@ClientWindowScoped,UUIDConverter, Jakarta Security, JoinFaces and Quarkus, which the rest of the section introduces, and on the Jakarta EE profiles. -
They describe libraries that ended (RichFaces, Tomahawk, Trinidad, Seam 2, Apache Shale) and portlet bridges; current choices are PrimeFaces, OmniFaces and Jakarta Security (security), covered on their own pages.
References
-
Jakarta Faces 4.1 specification document (HTML) — Appendix B, Change Log
-
Mojarra 4.1: context parameters (including
com.sun.faces.enableCspNonceandcom.sun.faces.cspPolicy)