Matt
Using branch
https://github.com/mraible/roller/tree/feature/jakarta-ee-10-migration
Upload now works.
Will do some more testing, but all looks OK.
####
One minor point I noticed, not related to your mods I think, the
uploaded confirmation page has a link "Create new weblog post" where it
adds the image to a new weblog post, but uses single quotes and the
image does not show correctly after saving/publishing (but should). Add
media file from the New Entry page works, and uses double quotes.
"Create new weblog post" link - incorrect - single quote
<a
href='http://127.0.0.1/app/testuser/mediaresource/cfc4d3cc-c498-4de9-8246-4b7281cd3ae6'><img
src='http://127.0.0.1/app/testuser/mediaresource/cfc4d3cc-c498-4de9-8246-4b7281cd3ae6?t=true'
alt='back.jpg' width='120' height='120'></img></a>
"New Entry, Add media file" link. - correct - double quotes
<a
href="http://127.0.0.1/app/testuser/mediaresource/9fe0d227-a43b-4a93-9f30-a7e3c935dab3"><img
src="http://127.0.0.1/app/testuser/mediaresource/9fe0d227-a43b-4a93-9f30-a7e3c935dab3?t=true"
alt="back.jpg" /></a>
On 12/08/2026 14:39, Matt Raible wrote:
Good catch, thanks Greg!
You were right about UploadedFilesAware. I migrated MediaFileAdd,
MediaFileEdit, and BookmarksImport (the three actions that receive uploads) to
it on the PR branch. The interceptor hands the action UploadedFile objects
directly now, so I also dropped the old FileName/ContentType arrays and read
the original name and content type straight off the upload.
On the renamed variable: I didn't need it. I kept the field private with no
getter/setter pair at all, so there's nothing for the params interceptor to
collide with and the natural name works fine.
I verified it end to end against a fresh install: a PNG uploads and is served
back byte-identical with the right content type, and an OPML bookmark import
works too. There's also a Playwright test in the stack now that registers a
user, enables uploads from the server admin page (they ship disabled), uploads
a file, and fetches it back, so this can't regress silently again. CI is green.
One thing to note if you're testing on that branch: the intermediate jakarta PR
still pairs the new bootstrap plugin's markup with the old Bootstrap 3 CSS, so
a few forms look a little rough there (stacked buttons, missing tooltip icons).
That all cleans up in the Bootstrap 5 PR that's stacked on top of it.
Cheers,
Matt
On Aug 12, 2026, at 02:13, Greg Huber<[email protected]> wrote:
Matt,
I gave it a quick spinup (not using docker, from your git repo), and it works
great.
I had to manually create the database (mariabd), which is normal, then roller
did the rest.
create database rollerdb;
grant all on rollerdb.* to scott@'%' identified by 'tiger';
grant all on rollerdb.* to scott@localhost identified by 'tiger';
One thing that did not work was the media upload. In struts 7 the upload logic
is changed, now have to implement UploadedFilesAware. Also, for some reason
the uploadedFiles variable needs to be different.
eg
public class MediaFileBase extends UIAction implements UploadedFilesAware {
// uploaded files
private List<UploadedFile> uploadedFilesz = null;
/**
* With uploaded files.
*
* @param uploadedFiles the uploaded files
*/
@Override
public void withUploadedFiles(List<UploadedFile> uploadedFiles) {
this.uploadedFilesz = uploadedFiles;
}
public List<UploadedFile> getUploadedFilesz() {
return uploadedFilesz;
}
}
Then use in MediaFileAdd
List<String> uploaded = new ArrayList<String>();
// File[] uploads = getUploadedFiles();
List<UploadedFile> uploads = getUploadedFilesz();
if (uploads != null && uploads.size() > 0) {
for (UploadedFile uploadedFile : uploads) {
String fileName = uploadedFile.getOriginalName();
etc...
}
}
Thanks.
On 12/08/2026 00:24, Matt Raible wrote:
Hi all,
I've been working on ROL-2183 (https://issues.apache.org/jira/browse/ROL-2183)
and have a PR up that migrates Roller from Java EE 8 to Jakarta EE
10:https://github.com/apache/roller/pull/154
The short version: Java 17 is now the minimum, and the big frameworks all moved
to their Jakarta-native versions. Struts 7.1, Spring Framework 7, Spring
Security 7, EclipseLink 5, and Tomcat 10.1 in the Docker image. The Jetty
plugin moved to Jetty 12, so mvn jetty:run works again for quick local
development with an in-memory Derby database.
A couple of things went away. OAuth 1.0a and OpenID 2.0 are both obsolete and
their libraries have no Jakarta-compatible releases, so I removed them. The
replacement is OAuth 2.0/OIDC login built on Spring Security's OAuth2 client,
and that's where the follow-up work comes in.
To keep #154 reviewable, I've stacked the follow-ups in my fork. OIDC login
with a seeded Keycloak in docker-compose is mraible/roller#3. Converting the
admin and editor UI from Bootstrap 3 to 5.3 is #4 (struts2-bootstrap-plugin
6.1.0 targets Jakarta and emits Bootstrap 5 markup). And #5 replaces the old
it-selenium module with Playwright browser tests that CI runs three ways:
database auth on Jetty, plus OIDC and mixed db-oidc against the Docker stack.
Each PR only shows its own diff, and I'll retarget them to apache/roller as the
level below merges.
Getting CI green on the migration branch turned up a few traps worth knowing about if
you're reviewing. Spring Security 7's XML config denies any request that doesn't match an
intercept-url rule, where the old FilterSecurityInterceptor allowed them, so every page
including the login page redirected to the login page until I added an explicit permitAll
catch-all. The old webjars servlet still extends the javax HttpServlet and took the whole
webapp down on a Jakarta container; WebJar assets are served natively from
META-INF/resources now. And struts2-bootstrap-plugin turned out to supply the FreeMarker
templates behind the theme="bootstrap" attribute on nearly every form, so
removing it as an unused taglib broke every form page. Restoring the Jakarta-native 6.1.0
fixed that, and the old Selenium journey (register, log in, create a weblog, publish an
entry) passes on the migration branch again.
If you want to try it, the quickest path is mvn -DskipTests install followed by mvn
jetty:run, thenhttp://localhost:8080/roller. For the OIDC branch, docker compose up
brings up Roller, PostgreSQL, and Keycloak seeded with admin/admin and user/user. You'll
need a "127.0.0.1 keycloak" line in /etc/hosts so the browser and the container
resolve the issuer the same way.
CI is green on the PR across JDK 17, 21, and 23, and I've been running the
Playwright suite against all three auth configurations locally. Review and
testing on other setups would be welcome, especially from anyone running LDAP
or container-managed auth, since those paths got mechanical updates but I don't
have an environment to exercise them.
Cheers,
Matt