Skip to content

ROL-2183: Migrate from javax to Jakarta EE 11 - #154

Open
mraible wants to merge 21 commits into
apache:masterfrom
mraible:feature/jakarta-ee-10-migration
Open

ROL-2183: Migrate from javax to Jakarta EE 11#154
mraible wants to merge 21 commits into
apache:masterfrom
mraible:feature/jakarta-ee-10-migration

Conversation

@mraible

@mraible mraible commented Aug 11, 2026

Copy link
Copy Markdown

Migrates Apache Roller from Java EE 8 (javax.*) to Jakarta EE 11 (jakarta.*), upgrading all major frameworks. The target started as EE 10; Copilot review pointed out Spring Framework 7 is only supported on the EE 11 baseline (Servlet 6.1), and the containers all support it, so the servlet API, Jetty, and Tomcat moved up. The branch name keeps its original ee-10 form. Each commit corresponds to a migration phase so reviewers can follow the progression. JIRA: ROL-2183

Target versions: Java 17, Servlet 6.1, Struts 7.1.1, Spring 7.0.8, Spring Security 7.0.6, EclipseLink 5.0.1, Jetty 12.1.12, Tomcat 11

Removed functionality — called out explicitly so nothing merges silently:

  • OAuth 1.0a is gone: the AtomPub API's oauth authentication option and the consumer key management UI. The net.oauth library is unmaintained and javax-only, and the protocol was obsoleted by OAuth 2.0 (RFC 6749, 2012). AtomPub authentication now offers basic and wsse only. The OIDC PR stacked on this one adds OAuth 2.0 for browser login; it does not cover AtomPub.
  • OpenID 2.0 login no longer works at this level: spring-security-openid was deleted upstream in Spring Security 6. The stacked OIDC PR replaces it with OpenID Connect and retires the openid/db-openid auth method values.

Everything else API-facing survives: Blogger/MetaWeblog XML-RPC and AtomPub are preserved by forking their javax-only servlets into Roller (xmlrpc-server and rome-propono have no Jakarta releases), and WebJar URLs are unchanged (Servlet 3.0+ serves META-INF/resources natively, so the javax-only webjars servlet could simply be dropped).

Behavior notes for reviewers:

  • The forked Atom adapter keeps propono’s null path info normalization, so a request to the exact /roller-services/app mapping serves the service document (caught by Copilot review; guarded by a smoke test in the Playwright PR).
  • docker-compose binds a new postgresql-16-data directory because PostgreSQL 16 cannot start on a data directory from the PostgreSQL 10 image the old file used (also from Copilot review).
  • AtomPub basic authentication is fixed: it verified the password against a field that is never set at that point, so every request got a 401. The bug exists on master too; the new web services smoke test in this stack caught it.
  • Media upload actions now implement Struts 7's UploadedFilesAware — Struts 7 removed the old File[]/setter injection, which silently broke uploads until Greg Huber caught it on dev@roller. Fixed and covered by a browser test in the Playwright PR of this stack.
  • Form markup at this level is emitted in Bootstrap 5 flavor by struts2-bootstrap-plugin 6.1.0 (the Jakarta-native release, which also supplies the form theme templates Roller relies on) while the page CSS is still Bootstrap 3, so a few forms look rough here (stacked buttons, missing tooltip icons). The Bootstrap 5 PR stacked on this one reconciles them.

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): OAuth 1.0a (14 files deleted, 17 edited), spring-security-openid (filter, beans, OpenID URL detection in RollerUserDetailsService/RollerSession), XmlRpcServlet and AtomServlet forked in, struts2-bootstrap-plugin upgraded 4.0.0 → 6.1.0.

Phase 2 — The big switch (one coordinated change since Struts 7, Spring 7, and Jakarta APIs are tightly coupled):

  • 320 javax.servlet/javax.mail/javax.activation imports converted to jakarta.* across 89 Java files
  • com.opensymphony.xwork2.* imports migrated to org.apache.struts2.*
  • Deprecated Struts interfaces (ServletRequestAware, RequestAware, HttpParametersAware) replaced with ActionContext lookups
  • Struts 7 runtime fixes: parameter binding is annotation-gated by default (struts.parameters.requireAnnotations=false since Roller's actions predate @StrutsParameter), an OGNL allowlist for Roller packages, the static content path, and the prepare interceptor re-enabled ahead of params
  • Spring Security AccessDecisionManager/RoleVoter removed, migrated to expression-based access control; Spring Security 7's authorization manager denies unmatched requests, so a permitAll catch-all preserves the old open-by-default behavior for public URLs
  • All Maven dependencies swapped to Jakarta equivalents
  • persistence.xml + 29 ORM files updated to Jakarta JPA namespace
  • web.xml, struts.xml, tiles.xml, security.xml config updated
  • JSP error pages updated (javax.servlet.error.*jakarta.servlet.error.*)
  • Password encoder constructors updated for Spring Security 7 API changes

Phase 3 — Build and deployment tooling:

  • Jetty Maven plugin upgraded from 10 to 12 (ee10 module for Jakarta servlet support)
  • mvn jetty:run fixed for the Jetty 12 plugin (jettyXml was renamed jettyXmls and 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 schema
  • Dockerfile updated: Tomcat 9 → 10.1, javax.mail → angus-mail, PostgreSQL driver updated
  • docker-compose.yml updated: PostgreSQL 10 → 16
  • CI matrix is now JDK 17, 21, and 25 (Java 11 dropped for the 17 baseline; 23 replaced by the 25 LTS, which required Mockito 5.23.0 to instrument JDK 25 class files)

All 157 unit tests pass on JDK 17, 21, and 25.

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.
@mraible

mraible commented Aug 11, 2026

Copy link
Copy Markdown
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 Jetty 12 plugin renamed jettyXml to jettyXmls and silently ignored the old name, so the it-selenium harness never loaded jetty.xml, never bound the JNDI datasource, and never started the Derby network server (Nothing to bind for name jdbc/rollerdb in the earlier run's log).
  • webjars-servlet-2.x extends the javax HttpServlet, so on a Jakarta container it threw NoClassDefFoundError at startup and took the whole context down. WebJar assets are now served natively from META-INF/resources at the same /webjars paths.
  • Spring Security 7's XML config authorizes through AuthorizationManager, which denies requests that match no intercept-url rule; the old FilterSecurityInterceptor allowed them. Every unlisted URL, including the login page itself, redirected to the login page in a loop. An explicit /** permitAll rule restores the old behavior.
  • struts2-bootstrap-plugin had been removed 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 with TemplateNotFoundException. The Jakarta-native 6.1.0 restores the theme; it emits Bootstrap 5 markup against the current Bootstrap 3 CSS, so some form styling is off until a follow-up converts the UI to Bootstrap 5.

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.
authenticateBASIC verified the supplied password against the handler's user field, which is only assigned after authentication returns, so the check always threw NullPointerException, was swallowed by the catch block, and every basic-auth request got a 401. The check now uses the account it just looked up. This bug exists on master too; the new web services smoke test in this stack caught it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates Roller to Java 17 and Jakarta APIs, upgrades its web stack and deployment tooling, and removes obsolete OAuth 1.0a/OpenID 2.0 integration.

Changes:

  • Migrates Servlet, JSP, Mail, Activation, JPA, Struts, Spring, Jetty, and Tomcat integrations.
  • Forks Jakarta-compatible AtomPub and XML-RPC servlet adapters and updates file uploads.
  • Removes OAuth 1.0a and modernizes build, CI, Docker, and database tooling.

Reviewed changes

Copilot reviewed 177 out of 186 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
testing/junit-cleartables-mysql.sql Removes OAuth cleanup.
pom.xml Sets Java 17 and Jetty 12.
it-selenium/src/test/java/org/apache/roller/selenium/editor/AbstractEntryPage.java Updates publish-button selection.
it-selenium/pom.xml Migrates integration tests to Jakarta and Jetty 12.
Dockerfile Updates build image, Tomcat, JDBC, and mail libraries.
docker-compose.yml Upgrades PostgreSQL.
app/src/test/resources/roller-jettyrun.properties Enables automatic test schema creation.
app/src/test/resources/jetty.xml Migrates Jetty JNDI configuration.
app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsModelTest.java Uses Jakarta Servlet API.
app/src/test/java/org/apache/roller/weblogger/ui/rendering/model/SearchResultsFeedModelTest.java Uses Jakarta Servlet API.
app/src/test/java/org/apache/roller/weblogger/ui/core/RollerSessionTest.java Uses Jakarta Servlet API.
app/src/test/java/org/apache/roller/weblogger/ui/core/filters/ValidateSaltFilterTest.java Uses Jakarta Servlet API.
app/src/test/java/org/apache/roller/weblogger/ui/core/filters/LoadSaltFilterTest.java Uses Jakarta Servlet API.
app/src/test/java/org/apache/roller/weblogger/business/jpa/JPAOAuthManagerTest.java Removes obsolete OAuth tests.
app/src/main/webapp/WEB-INF/web.xml Migrates deployment descriptor and removes OAuth/WebJars servlets.
app/src/main/webapp/WEB-INF/tiles.xml Updates Tiles and removes OAuth views.
app/src/main/webapp/WEB-INF/security.xml Migrates Spring Security authorization and removes OpenID.
app/src/main/webapp/WEB-INF/jsps/taglibs-struts2.jsp Removes obsolete Bootstrap taglib.
app/src/main/webapp/WEB-INF/jsps/core/OAuthKeys.jsp Removes OAuth key UI.
app/src/main/webapp/WEB-INF/jsps/core/OAuthAuthorize.jsp Removes OAuth authorization UI.
app/src/main/webapp/WEB-INF/jsps/core/MainMenuSidebar.jsp Removes OAuth navigation.
app/src/main/webapp/roller-ui/logout-redirect.jsp Uses Jakarta cookies.
app/src/main/webapp/roller-ui/errors/error.jsp Uses Jakarta error attributes.
app/src/main/webapp/roller-ui/errors/404.jsp Uses Jakarta error attributes.
app/src/main/webapp/roller-ui/errors/403.jsp Uses Jakarta error attributes.
app/src/main/resources/struts.xml Migrates Struts configuration and interceptors.
app/src/main/resources/sql/droptables.sql Removes OAuth tables from teardown.
app/src/main/resources/sql/createdb.vm Removes OAuth schema creation.
app/src/main/resources/sql/510-to-520-migration.vm Removes OAuth migration operations.
app/src/main/resources/sql/400-to-500-migration.vm Removes OAuth schema migration.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogTemplate.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogPermission.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogHitCount.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryTagAggregate.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryTag.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryComment.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntryAttribute.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogEntry.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogCategory.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmarkFolder.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/WeblogBookmark.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/Weblog.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/UserRole.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/User.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/TaskLock.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/RuntimeConfigProperty.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/PingTarget.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/PingQueueEntry.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/ObjectPermission.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/OAuthConsumerRecord.orm.xml Removes OAuth persistence mapping.
app/src/main/resources/org/apache/roller/weblogger/pojos/OAuthAccessorRecord.orm.xml Removes OAuth persistence mapping.
app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFileTag.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/MediaFile.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/CustomTemplateRendition.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/weblogger/pojos/AutoPing.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/planet/pojos/SubscriptionEntry.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/planet/pojos/Subscription.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/planet/pojos/RuntimeConfigProperty.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/planet/pojos/PlanetGroup.orm.xml Migrates ORM namespace.
app/src/main/resources/org/apache/roller/planet/pojos/Planet.orm.xml Migrates ORM namespace.
app/src/main/resources/META-INF/persistence.xml Migrates persistence descriptor and removes OAuth mappings.
app/src/main/resources/ApplicationResources.properties Removes OAuth messages.
app/src/main/resources/ApplicationResources_zh_CN.properties Removes translated OAuth messages.
app/src/main/java/org/apache/roller/weblogger/webservices/xmlrpc/RollerXmlRpcServletServer.java Adds Jakarta XML-RPC server adapter.
app/src/main/java/org/apache/roller/weblogger/webservices/xmlrpc/RollerXmlRpcServlet.java Adds Jakarta XML-RPC servlet.
app/src/main/java/org/apache/roller/weblogger/webservices/tagdata/TagDataServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/webservices/opensearch/OpenSearchServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/webservices/oauth/RequestTokenServlet.java Removes OAuth request-token endpoint.
app/src/main/java/org/apache/roller/weblogger/webservices/oauth/AuthorizationServlet.java Removes OAuth authorization endpoint.
app/src/main/java/org/apache/roller/weblogger/webservices/oauth/AccessTokenServlet.java Removes OAuth access-token endpoint.
app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomRequestImpl.java Adds Jakarta Atom request adapter.
app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandlerFactory.java Removes javax-based handler factory.
app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java Migrates Atom handling and fixes basic authentication.
app/src/main/java/org/apache/roller/weblogger/util/Utilities.java Migrates mail and activation APIs.
app/src/main/java/org/apache/roller/weblogger/util/MailUtil.java Migrates mail API.
app/src/main/java/org/apache/roller/weblogger/util/I18nMessages.java Updates Struts class reference.
app/src/main/java/org/apache/roller/weblogger/ui/tags/WordWrapTag.java Uses Jakarta JSP API.
app/src/main/java/org/apache/roller/weblogger/ui/tags/TruncateNicelyTag.java Uses Jakarta JSP API.
app/src/main/java/org/apache/roller/weblogger/ui/tags/StringTagSupport.java Uses Jakarta JSP API.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/util/UISecurityInterceptor.java Migrates Struts imports.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/util/UIActionPrepareInterceptor.java Migrates Struts imports.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/util/UIActionInterceptor.java Migrates Servlet and Struts imports.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/util/UIAction.java Replaces request injection with ActionContext.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Members.java Reads parameters through ActionContext.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileEdit.java Migrates replacement uploads to Struts 7.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java Migrates media uploads to Struts 7.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/FolderEdit.java Replaces response injection with ActionContext.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarksImport.java Migrates OPML uploads to Struts 7.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Register.java Replaces request injection with ActionContext.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/OAuthKeys.java Removes OAuth key action.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/OAuthAuthorize.java Removes OAuth authorization action.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/ajax/UserDataServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/ajax/ThemeDataServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/ajax/CommentDataServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/GlobalConfig.java Replaces legacy Struts-aware interfaces.
app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/GlobalCommentManagement.java Replaces request injection.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/WeblogRequestMapper.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/velocity/WebappResourceLoader.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogTrackbackRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogSearchRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogResourceRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogPreviewResourceRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogPreviewRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogPageRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogMediaResourceRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogFeedRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/WeblogCommentRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/PlanetRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ParsedRequest.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/MobileDeviceRepository.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDeviceResolver.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceUtils.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceResolver.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/TrackbackServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java Uses Jakarta Servlet/JSP APIs.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/RSDServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/ResourceServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewServlet.java Uses Jakarta Servlet/JSP APIs.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewResourceServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PlanetFeedServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java Uses Jakarta Servlet/JSP APIs.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/MediaResourceServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/FeedServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/CommentServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/CommentAuthenticatorServlet.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/RequestMapper.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/plugins/comments/MathCommentAuthenticator.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/plugins/comments/LdapCommentAuthenticator.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/plugins/comments/DefaultCommentAuthenticator.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/plugins/comments/CommentAuthenticatorUtils.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/plugins/comments/CommentAuthenticator.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/model/CalendarModel.java Uses Jakarta JSP API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/mobile/MobileDeviceRepository.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/filters/RequestMappingFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/rendering/filters/DeviceResolverRequestFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/tags/calendar/CalendarTag.java Uses Jakarta JSP API.
app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerUserDetailsService.java Removes OpenID lookup behavior.
app/src/main/java/org/apache/roller/weblogger/ui/core/security/CustomUserRegistry.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/security/BasicUserAutoProvision.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/security/AutoProvision.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java Migrates sessions and removes OpenID fallback.
app/src/main/java/org/apache/roller/weblogger/ui/core/RollerContext.java Migrates Servlet API and password encoders.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/ValidateSaltFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/SpringFirewallExceptionFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/RoleAssignmentFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/PersistenceSessionFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/LoadSaltFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/IPBanFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/InitFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/DebugFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/CustomOpenIDAuthenticationProcessingFilter.java Removes OpenID filter.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/CharEncodingFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/filters/BootstrapFilter.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/ui/core/CmaRollerContext.java Uses Jakarta Servlet API.
app/src/main/java/org/apache/roller/weblogger/pojos/OAuthConsumerRecord.java Removes OAuth consumer model.
app/src/main/java/org/apache/roller/weblogger/pojos/OAuthAccessorRecord.java Removes OAuth accessor model.
app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroupSubs.java Migrates preparation to Struts 7.
app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroups.java Replaces request injection.
app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetConfig.java Reads parameters through ActionContext.
app/src/main/java/org/apache/roller/weblogger/business/WebloggerImpl.java Removes OAuth manager wiring.
app/src/main/java/org/apache/roller/weblogger/business/Weblogger.java Removes OAuth manager API.
app/src/main/java/org/apache/roller/weblogger/business/URLStrategy.java Removes OAuth URL API.
app/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManagerImpl.java Uses Jakarta Activation API.
app/src/main/java/org/apache/roller/weblogger/business/OAuthManager.java Removes OAuth manager API.
app/src/main/java/org/apache/roller/weblogger/business/MultiWeblogURLStrategy.java Removes OAuth URL generation.
app/src/main/java/org/apache/roller/weblogger/business/MailProvider.java Uses Jakarta Mail API.
app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java Removes OAuth bindings.
app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerImpl.java Removes OAuth dependency injection.
app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAOAuthManagerImpl.java Removes OAuth persistence implementation.
app/src/main/java/org/apache/roller/planet/util/MailUtil.java Uses Jakarta Mail API.
app/pom.xml Upgrades Jakarta, Spring, Struts, persistence, and test dependencies.
.github/workflows/main.yml Updates branch coverage and JDK matrix.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/pom.xml
Comment thread docker-compose.yml
…eusing the PostgreSQL 10 data directory

The rome-propono adapter the AtomPub servlet was forked from normalizes a null path info to an empty string, and dropping that in the fork made a request to the exact /roller-services/app mapping fail with a 500 instead of serving the Atom service document. docker-compose now binds a new postgresql-16-data directory, since PostgreSQL 16 refuses to start on a data directory initialized by the PostgreSQL 10 image this file used before. Both found by Copilot review on the pull request.
…line

Spring Framework 7 is built against Servlet 6.1 and its supported platform is Jakarta EE 11, so pairing it with Servlet 6.0 on Jetty 12.0 and Tomcat 10.1 was an unsupported combination that could break whenever Spring reaches a 6.1-only API. The servlet API moves to 6.1.0, the Jetty plugin to the ee11 flavor at 12.1.12, and the Docker image to Tomcat 11. JSP was already at the EE 11 level. Raised by Copilot review on the pull request.
@mraible mraible changed the title ROL-2183: Migrate from javax to Jakarta EE 10 Migrate from Java EE 8 to Jakarta EE 11 Aug 13, 2026
@mraible mraible changed the title Migrate from Java EE 8 to Jakarta EE 11 ROL-2183: Migrate from javax to Jakarta EE 11 Aug 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 177 out of 187 changed files in this pull request and generated 29 comments.

Suppressed comments (4)

app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomServlet.java:180

  • A collection POST without a Content-Type never reaches the intended 415 branch below because this dereference throws first; the broad catch converts it to a 500. Guard the value before calling startsWith so malformed clients receive SC_UNSUPPORTED_MEDIA_TYPE.
    app/src/test/resources/roller-jettyrun.properties:62
  • These instructions cannot work on this branch: AuthMethod has no oidc value, and this compose file has no Keycloak service. Since the PR description says OIDC is supplied only by the stacked follow-up, move this block to that PR rather than directing jetty:run users to an unsupported configuration.
    app/src/main/webapp/WEB-INF/web.xml:5
  • The PR targets Servlet 6.1 / Jakarta EE 11, but the deployment descriptor still declares the Servlet 6.0 schema and version. Update both values to 6.1 so the application descriptor actually declares the baseline stated by this PR.
    app/src/main/webapp/WEB-INF/web.xml:454
  • Changing the resource type here leaves both docs/roller-install-guide.adoc (lines 466 and 506) and META-INF/context.xml-example (line 25) instructing Tomcat users to bind javax.mail.Session. On this Jakarta-only runtime that resource type no longer matches this declaration, so the documented JNDI deployment path fails. Update those installation examples to jakarta.mail.Session as part of the migration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants