Apache Struts 1.3.x Forward Compatibility Container Support
Verified application server and JDK combinations for NES for Apache Struts 1.3.x Forward Compatibility
Overview
NES for Apache Struts 1.3.x Forward Compatibility targets Jakarta EE 9 (Servlet 5.0) and Java 11. It also runs on newer servlet containers and newer JDKs. This page records the combinations that have been verified by running the full Struts example application suite against each one, and the configuration each container family requires.
Verified combinations
Each cell was exercised by deploying the eight Struts example applications and requesting a page from each, plus a multipart/form-data upload.
| Application server | Servlet | Jakarta EE | Java 11 | Java 17 | Java 21 |
|---|---|---|---|---|---|
| Apache Tomcat 10.1 | 6.0 | 10 | Yes | Yes | Yes |
| Apache Tomcat 11.0 | 6.1 | 11 | — | Yes | Yes |
| Eclipse Jetty 12 | 6.0 | 10 | — | Yes | Yes |
| WildFly 30 | 6.0 | 10 | Yes | Yes | Yes |
| WildFly 40 | 6.1 | 11 | — | Yes | Yes |
| GlassFish 8 | 6.1 | 11 | — | — | Yes |
A dash means the application server itself does not support that JDK, not that Struts fails there:
- Tomcat 11, Jetty 12 and WildFly 40 require Java 17 or later.
- GlassFish 8 requires Java 21.
The core framework — struts-core, struts-taglib, struts-tiles and struts-el — works on every combination marked Yes. The struts-faces module is subject to the limitation described below.
Jakarta EE application servers
Full Jakarta EE servers such as WildFly and GlassFish supply their own Jakarta Faces and CDI implementations, which changes what your application has to provide.
Add a CDI bean archive marker
On a Jakarta EE server, Jakarta Faces 4 initializes for every deployed web module and refuses to start unless the module is a CDI bean archive. Without this, deployment fails with IllegalStateException: CDI is not available, even for an application that uses no Faces and no CDI at all.
Add an empty bean archive marker to each web application:
<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_3_0.xsd"
version="3.0"
bean-discovery-mode="annotated">
</beans>
This is required on GlassFish 8 for all web applications. On WildFly it is required only for applications that use Jakarta Faces.
Do not bundle a CDI implementation
If your web application bundles weld-servlet-shaded so that CDI is available on a plain servlet container, remove it before deploying to a Jakarta EE server. Its ServletContainerInitializer collides with the CDI implementation the server already provides, and deployment fails with:
Error invoking ServletContainerInitializer org.jboss.weld.environment.servlet.EnhancedListener
Package every tag library class you reference
GlassFish instantiates every tag class in every TLD on the classpath at deployment time, where Tomcat and Jetty load a tag class only when a page actually uses it. A tag library whose implementation classes are missing therefore deploys fine on Tomcat and fails to start on GlassFish.
The common case is struts-el, which ships struts-tiles-el.tld but declares struts-tiles as an optional dependency. If you use struts-el, add struts-tiles explicitly:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-tiles</artifactId>
<version>1.3.10-struts-1.4.5</version>
</dependency>
Otherwise deployment fails with NoClassDefFoundError: org/apache/struts/tiles/taglib/InsertTag.
Jakarta Faces support
struts-faces requires Jakarta Faces 3.x. It does not work on Jakarta Faces 4.
The struts-faces tag library is built on the Jakarta Faces JSP tag API — UIComponentELTag and UIComponentClassicTagBase. That API was deprecated in Faces 3.0 and removed in Faces 4.0, which supports Facelets views only. As a result:
- Supported: servlet containers where you supply Jakarta Faces yourself and can pin a 3.x implementation, such as Tomcat 10.1 and Jetty 12.
- Not supported: Jakarta EE 10 and 11 application servers, which ship Faces 4 and use it in preference to any implementation bundled in your application. On WildFly 30 and later and on GlassFish 8, Faces views resolve as Facelets and requests fail with
FacesException: /<view>.xhtml Not Found in ExternalContext as a Resource. - Not supported: Apache Tomcat 11. Jakarta Pages 4.0 does not run the Faces 3.x JSP view path correctly; pages render an empty response body.
Applications that use struts-faces should stay on a Jakarta EE 9 or 10 servlet container with Faces 3.x. Migrating the views from JSP to Facelets is required before moving to a Faces 4 environment.
Request character encoding
Apache Tomcat sets a default request character encoding in its conf/web.xml:
<request-character-encoding>UTF-8</request-character-encoding>
Most other containers, including Jetty and WildFly's Undertow, leave the request encoding unset when the client does not send one. Code that assumes ServletRequest.getCharacterEncoding() returns a value will behave differently on those containers.
Note
On 1.3.10-struts-1.4.4 and earlier, a multipart/form-data POST that does not declare a charset fails on containers that do not default the request encoding, with IllegalArgumentException: Null charset name. This is fixed in 1.3.10-struts-1.4.5. If you cannot upgrade, set the request encoding explicitly — for example with a servlet filter that calls ServletRequest.setCharacterEncoding — when deploying to Jetty, WildFly or GlassFish.
Scripting support
struts-scripting uses Apache BSF to run script actions. If you use it with Groovy, the Groovy version matters on newer JDKs.
Groovy 1.x calls setAccessible on JDK-internal members. JEP 396 made that a hard failure in Java 16, so on Java 17 and later the engine fails to load and the request fails with:
org.apache.bsf.BSFException: unable to load language: groovy
Use Groovy 3 with its BSF engine, which needs no --add-opens flags on Java 11, 17 or 21:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.25</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-bsf</artifactId>
<version>3.0.25</version>
</dependency>
Groovy 3 is the newest line that ships a BSF engine; groovy-bsf was discontinued after Groovy 4.0.0-alpha-2.