ROL-2183: Migrate from javax to Jakarta EE 10 - #154
Open
mraible wants to merge 17 commits into
Open
Conversation
Phase 0 of the javax to Jakarta EE 10 migration (ROL-2183). - Set compiler target from Java 11 to Java 17 (required by Spring 7, Struts 7) - Upgrade Derby from 10.11.1.1 to 10.16.1.1 (old version doesn't support Java 17) - Fix SLF4J bridge: log4j-slf4j-impl is for SLF4J 1.x, switch to log4j-slf4j2-impl to match the SLF4J 2.0.16 already declared in app/pom.xml
Phase 1 of the Jakarta EE 10 migration removes unmaintained and obsolete dependencies while still on the javax namespace so changes can be tested incrementally. - Remove all OAuth 1.0a support (net.oauth.core:oauth-provider): 3 servlets, OAuthManager interface and JPA implementation, Struts actions, JSPs, ORM mappings, SQL schema, Guice bindings, and test - Remove spring-security-openid: delete CustomOpenIDAuthenticationProcessingFilter, remove OpenID beans from security.xml, simplify RollerUserDetailsService and RollerSession to remove OpenID URL detection - Remove struts2-bootstrap-plugin (unused taglib, never referenced in JSPs) - Remove OAuth URL methods from URLStrategy and MultiWeblogURLStrategy - Remove OAuth authentication path from RollerAtomHandler (keep WSSE and BASIC) - Clean up ApplicationResources properties files (EN, JA, ZH_CN) to remove OAuth keys/authorize entries
These servlets come from xmlrpc-server and rome-propono respectively, neither of which has a Jakarta Servlet compatible release. Forking the servlet classes into Roller decouples us from their javax.servlet dependency so the imports can be converted to jakarta.servlet in Phase 2. - Fork XmlRpcServlet and XmlRpcServletServer from Apache XML-RPC 3.1.3 into org.apache.roller.weblogger.webservices.xmlrpc package - Fork AtomServlet from rome-propono into RollerAtomServlet, which directly creates RollerAtomHandler instead of using propono's factory lookup - Update web.xml servlet-class references to point to the forked classes - Both libraries remain as dependencies for their non-servlet infrastructure classes
The big switch: all javax Java EE APIs replaced with Jakarta equivalents, all major frameworks upgraded to Jakarta-compatible versions. Dependencies: javax.servlet-api 4.0.1 → jakarta.servlet-api 6.0.0, javax.mail → jakarta.mail-api 2.1.3 + angus-mail 2.0.3, javax.activation → jakarta.activation-api 2.1.3, jaxb-api → jakarta.xml.bind-api 4.0.2 + jaxb-runtime 4.0.5, JSTL 1.2 → jakarta.servlet.jsp.jstl-api 3.0.1, Struts 2.5.29 → 7.1.1, Spring 5.3.39 → 7.0.8, Spring Security 5.8.14 → 7.0.6, EclipseLink 4.0.5 → 5.0.1 Java source: 320 javax.servlet/mail/activation imports converted to jakarta across 89 files, xwork2 imports migrated to org.apache.struts2 package, deprecated Struts interfaces (ServletRequestAware, RequestAware, HttpParametersAware) replaced with ActionContext lookups Spring Security: AccessDecisionManager/RoleVoter removed (deprecated in 6.0), migrated to expression-based access control with hasAuthority/hasAnyAuthority, password encoder constructors updated to factory methods Config: web.xml namespace updated to jakartaee 6.0, struts.xml DTD updated to Struts 7.0, persistence.xml and 29 ORM files updated to Jakarta JPA 3.2 namespace, tiles.xml DTD updated to 3.0, security.xml migrated to Spring Security 7 patterns Also: forked AtomRequestImpl from rome-propono to use jakarta.servlet, deleted dead RollerAtomHandlerFactory, fixed FolderEdit ServletResponseAware removal
Jetty 10 used javax.servlet and was incompatible with the Jakarta EE 10 migration. Jetty 12's ee10 module supports jakarta.servlet natively. The Dockerfile now targets Tomcat 10.1 (Jakarta EE 10) with angus-mail replacing the old javax.mail JAR.
The Jakarta EE 10 migration sets Java 17 as the compiler target, so the JDK 11 build matrix entry is no longer valid.
Update it-selenium/pom.xml to replace javax dependencies removed from the parent pom: javax.xml.bind → jakarta.xml.bind, javax.mail → jakarta.mail + angus-mail. Switch Jetty plugin to ee10 variant and update config for Jetty 12.
Struts 7.1.1 ships with struts-6.5.dtd as the latest DTD. The non-existent struts-7.0.dtd URL causes startup failures when the XML parser cannot fetch the DTD (e.g., in Docker containers without full internet access).
Struts 7 renamed the fileUpload interceptor to actionFileUpload. This causes a startup failure when Struts initializes the interceptor stack.
Struts 7 only binds request parameters to @StrutsParameter-annotated properties and denies OGNL access to classes outside its allowlist, which silently broke every form in the application. Also re-enables the prepare interceptor before params so Preparable actions load the object that submitted values are bound onto, and converts PlanetGroupSubs to the standard Preparable contract.
The plugin renamed jettyXml to jettyXmls and silently ignored the old parameter, so jetty.xml was never loaded. That file also needed updating for Jetty 12: a DOCTYPE is now required, plus.jndi.Resource takes the server ref as scope instead of a string, and MailSessionReference no longer exists so the mail session is built from angus-mail directly. The Derby datasource moves from commons-dbcp 1.4 to commons-dbcp2, and roller-jettyrun.properties uses installation.type=ittest so the schema is created at startup and jetty:run comes up ready to log in.
The XML namespace now authorizes through AuthorizationManager, which denies any request that matches no intercept-url rule, where the old FilterSecurityInterceptor allowed them. Every unlisted URL including the login page itself redirected to the login page in an infinite loop.
…rvlet webjars-servlet-2.x extends the javax HttpServlet, so loading it on a Jakarta container throws NoClassDefFoundError at startup and takes the whole context down with a 503. Servlet 3.0+ containers serve jar META-INF/resources content from the docroot at the same /webjars paths, so the servlet is unnecessary.
…ugin The plugin was removed earlier in the migration as an unused taglib, but it also supplies the FreeMarker templates behind the theme="bootstrap" attribute that nearly every form JSP uses, so any page with a form failed to render with TemplateNotFoundException. Version 6.1.0 is Jakarta-native. It emits Bootstrap 5 markup while the JSPs still ship Bootstrap 3 CSS, so some form styling is off until the UI is converted to Bootstrap 5 in a follow-up. This also drops the webjars-servlet-2.x dependency whose servlet was removed from web.xml.
The plugin renamed jettyXml to jettyXmls and silently ignored the old parameter, so jetty.xml never loaded, the JNDI datasource was never bound, the Derby network server never started, and every test met a 503. The datasource in that file now uses commons-dbcp2, so the plugin classpath follows. The publish button is now located by its btn-success class because its generated id changed between form-theme versions.
Author
|
The CI failures here predate the latest push: both runs failed the same way, with the it-selenium test meeting a 503 because the webapp never actually deployed. Debugging that locally turned up a chain of real migration bugs that the branch's only container test had been hiding, now fixed in the last four commits:
The full Selenium journey (register, log in, create a weblog, publish an entry) and the 157 unit tests pass locally on this branch after these changes. |
Struts 7 removed the old file upload parameter injection (File[] plus FileName/ContentType setters), so MediaFileAdd, MediaFileEdit, and BookmarksImport never received uploaded files. Each action now implements UploadedFilesAware and reads the file, original name, and content type from the UploadedFile objects supplied by the actionFileUpload interceptor. The upload fields are no longer exposed as getter/setter pairs so the params interceptor cannot collide with the form field names. Reported by Greg Huber on dev@roller.
The CI matrix moves from JDK 23 to JDK 25, the current LTS. Mockito 5.15.2 cannot instrument JDK 25 class files, which fails 19 session and filter tests, so it moves to 5.23.0. All 157 unit tests pass on 17, 21, and 25.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrates Apache Roller from Java EE 8 (
javax.*) to Jakarta EE 10 (jakarta.*), upgrading all major frameworks. Each commit corresponds to a migration phase so reviewers can follow the progression. JIRA: ROL-2183Target versions: Java 17, Servlet 6.0, Struts 7.1.1, Spring 7.0.8, Spring Security 7.0.6, EclipseLink 5.0.1, Jetty 12.0.21, Tomcat 10.1
Phase 0 — Java 17 baseline, Derby 10.16.1.1 (old version does not support Java 17), SLF4J 2.x bridge fix
Phase 1 — Remove unmaintained/obsolete dependencies while still on javax (testable incrementally):
Phase 2 — The big switch (must be done as one coordinated change since Struts 7, Spring 7, and Jakarta APIs are tightly coupled):
javax.servlet/javax.mail/javax.activationimports converted tojakarta.*across 89 Java filescom.opensymphony.xwork2.*imports migrated toorg.apache.struts2.*struts.parameters.requireAnnotations=falsesince Roller's actions predate@StrutsParameter), an OGNL allowlist for Roller packages, the static content path, and the prepare interceptor re-enabled ahead of paramsjavax.servlet.error.*→jakarta.servlet.error.*)Phase 3 — Build and deployment tooling:
mvn jetty:runfixed for the Jetty 12 plugin (jettyXmlwas renamedjettyXmlsand silently ignored, Jetty 12 jetty.xml syntax, a mail session built from angus-mail, commons-dbcp2) and it now comes up with a ready-to-use in-memory Derby schemaAll 157 tests pass across all phases.