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
