Wednesday, June 5, 2024

What's new in Faces 4.1?


At 5 June 2024, Faces 4.1 has been released! It's a maintenance release within the umbrella of Jakarta EE 11.

While working towards Faces 5.0 the Mojarra and MyFaces committers found relatively a lot of things that were unintentionally left unpolished in the 4.0 release and hence there was the desire to release an intermediate version 4.1 whereby a few more things were deprecated that already should have been deprecated in 4.0, and a few oversights in changes were caught up that should have been implemented in 4.0, and some inconsitenties in javadocs were fixed. While at it, we added a small handful of relatively simple things on community demand.


Here's an overview based on Faces 4.1 milestone of what's changed in Faces 4.1 as compared to Faces 4.0.

More deprecations

Catching up missing changes

Fixing spec/documentation

Addition of new stuff

Deprecate unused <cc:extension>

#1549: The <cc:extension> was originally intended as a placeholder to hold design time metadata for visual code editors as per JSR-276, but the entire design time thing never took off and the JSR-276 proposal went dormant. This rendered the <cc:extension> entirely unused. It's now finally marked deprecated for removal.

Deprecate unused @PostConstruct/@PreDestroyCustomScopeEvent

#1707: The @CustomScoped annotation was deprecated in JSF 2.3 and removed in Faces 4.0 in favor of custom CDI scopes. However the associated @PostConstructCustomScopeEvent and @PreDestroyCustomScopeEvent classes were overlooked during the deprecation process in JSF 2.3. With the removal of @ManagedBean and @CustomScoped in Faces 4.0 these event classes became completely unused. They're now finally marked deprecated for removal.

Deprecate discommended Full State Saving

#1829: The in JSF 2.0 introduced Partial State Saving (PSS) has proven its advantages. More performant and less memory consumption. The original Full State Saving (FSS) was discommended/discouraged since JSF 2.0 but it was still supported for backwards compatibility reasons and as fallback in case a bug with PSS was encountered. The original thought was to deprecate FSS in JSF 3.0 but this completely slipped through during the Java EE -> Jakarta EE chaos. It's now finally marked deprecated for removal.

Deprecate duplicated ActionSource2 and improved original ActionSource

#1832: The ActionSource interface was introduced in JSF 1.0. During JSF 1.2 there was the desire to add new methods to the interface but this would break backwards compatibility at compile level. Today we could just have added them as so-called default methods of the interface, but this was only introduced in Java 8 which wasn't yet released at that time. So in JSF 1.2 a new interface was added, ActionSource2, which simply extends the original interface. It could have been "rolled back" in JSF 2.3, the first JSF version which required a minimum of Java SE 8, but this didn't happen. We now finally took the opportunity to deprecate ActionSource2 and add its "new" methods as default methods of ActionSource.

Missing generic types which should have been added in 4.0

#1708 and #1789: During Faces 4.0 some work was done to add generic types to existing argument/return types in Faces API representing raw Collection or Map or Object. However in a few places these were overlooked, the ExternalContextWrapper#getInitParameterMap(), Renderer#getConvertedValue(), FacesMessage.VALUES and FacesMessage.VALUES_MAP. It has been caught up in Faces 4.1.

Deprecated UIComponent.bindings field should have been removed in 4.0

#1725: The protected field UIComponent.bindings was introduced in JSF 1.2 and immediately deprecated in JSF 2.0 in favor of set/getValueExpression(). It should already have been removed in Faces 4.0 along with ValueBinding and friends, but that slipped through. It has finally been removed in Faces 4.1.

Spec/documentation has been fixed

  • #1712: Fixed wrong reference to non-existent variable name "context" in Application#subscribeToEvent javadoc.
  • #1739: Explicitly require that CDI lifecycle events @Initialized, @BeforeDestroyed and @Destroyed must be fired for custom CDI scopes @ViewScoped and @FlowScoped. These were only weakly encouraged by CDI spec, which means that Faces implementors didn't necessarily have to fire them. From now on it's set in stone that the Faces implementors must fire them.
  • #1760: The id attribute of <h:head>/<h:body> was missing in vdldoc. The attributes were added to JSF 2.2 during HTML5 work but it wasn't correctly added to VDL documentation and then unintentionally disappeared from VDL documentation during VDL-related code deduplication efforts in JSF 2.3. It has now been added back.
  • #1811: The if attribute of <f:viewAction> was missing in vdldoc. It is actually a facade of rendered attribute but it wasn't made entirely clear in the VDL documentation because it was still labeled as rendered attribute. It's now correctly labeled as if attribute.
  • #1821: Explicitly specify default value of jakarta.faces.FACELETS_REFRESH_PERIOD in development stage. This was nowhere specified, causing the implementations to have different default values for this. It's now set in stone that this should default to 0 in development stage.
  • #1828: Remove references to already-removed facelets.XYZ context params in javadoc. The old facelets.XYZ context params were already removed in Faces 4.0, but they were still mentioned in some places in the javadocs. These references have now been removed.
  • #1864: The rowStatePreserved attribute of <h:dataTable> was missing in vdldoc. The attribute was added to JSF 2.1 but it was only added to "render kit doc" and wasn't added to VDL documentation. It has now been added to VDL documentation.

Add rowStatePreserved attribute to <ui:repeat>

#1263: The <h:dataTable> already had support for the rowStatePreserved attribute since JSF 2.1 in order to properly deal with <h:form> components within <h:dataTable>. This was only missing in <ui:repeat> and has now been added. It should only be used when the <ui:repeat> has nested <h:form> components which in turn have nested EditableValueHolder components such as <h:inputText>. It is not necessary when the nested forms only have nested ActionSource components such as <h:commandButton>.

Support @Inject of current Flow

#1342: The facesContext.getApplication().getFlowHandler().getCurrentFlow() slipped through during the efforts to make as many as possible Faces artifacts injectable via CDI. It's now injectable as @Inject Flow flow;.

Added ExternalContext#setResponseContentLengthLong()

#1764: The HttpServletResponse#setResponseContentLengthLong() which takes a long argument instead of int argument, so that it could support over 2GB, was added during Servlet 3.1 and the intent was to add it to JSF 3.0 as well (JSF 2.3 still had Servlet 3.0 as minimum requirement), but that slipped through during the Java EE -> Jakarta EE chaos. It has finally been added to Faces 4.1.

New UUIDConverter

#1819: a new default converter has been added for bean properties of java.util.UUID type: the jakarta.faces.convert.UUIDConverter identified by converter ID jakarta.faces.UUID. This is particularly to align with Jakarta Persistence 3.1 which introduced support for UUID as entity keys.

FacesMessage has now a default equals(), hashCode() and toString()

#1823: The FacesMessage didn't have an identity for a long time and couldn't be reliably compared/checked by identity. It didn't have default implementations of equals() and hashCode(). These have finally been added in Faces 4.1, along with the toString().