ROL-2183: Migrate from javax to Jakarta EE 11 - #154
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.
|
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.
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.
There was a problem hiding this comment.
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.
…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.
There was a problem hiding this comment.
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-Typenever reaches the intended 415 branch below because this dereference throws first; the broad catch converts it to a 500. Guard the value before callingstartsWithso malformed clients receiveSC_UNSUPPORTED_MEDIA_TYPE.
app/src/test/resources/roller-jettyrun.properties:62 - These instructions cannot work on this branch:
AuthMethodhas nooidcvalue, 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 directingjetty:runusers 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) andMETA-INF/context.xml-example(line 25) instructing Tomcat users to bindjavax.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 tojakarta.mail.Sessionas part of the migration.
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-2183Target 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:
oauthauthentication option and the consumer key management UI. Thenet.oauthlibrary is unmaintained and javax-only, and the protocol was obsoleted by OAuth 2.0 (RFC 6749, 2012). AtomPub authentication now offersbasicandwsseonly. The OIDC PR stacked on this one adds OAuth 2.0 for browser login; it does not cover AtomPub.spring-security-openidwas deleted upstream in Spring Security 6. The stacked OIDC PR replaces it with OpenID Connect and retires theopenid/db-openidauth method values.Everything else API-facing survives: Blogger/MetaWeblog XML-RPC and AtomPub are preserved by forking their javax-only servlets into Roller (
xmlrpc-serverandrome-proponohave no Jakarta releases), and WebJar URLs are unchanged (Servlet 3.0+ servesMETA-INF/resourcesnatively, so the javax-only webjars servlet could simply be dropped).Behavior notes for reviewers:
/roller-services/appmapping serves the service document (caught by Copilot review; guarded by a smoke test in the Playwright PR).postgresql-16-datadirectory because PostgreSQL 16 cannot start on a data directory from the PostgreSQL 10 image the old file used (also from Copilot review).UploadedFilesAware— Struts 7 removed the oldFile[]/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.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):
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 paramspermitAllcatch-all preserves the old open-by-default behavior for public URLsjavax.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 unit tests pass on JDK 17, 21, and 25.