Skip to content

[jaxrs-spec][quarkus] Migrate the Jakarta path to Quarkus REST and fix file upload types#24455

Open
Ignacio-Vidal wants to merge 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:jaxrs-spec-quarkus-rest-migration
Open

[jaxrs-spec][quarkus] Migrate the Jakarta path to Quarkus REST and fix file upload types#24455
Ignacio-Vidal wants to merge 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:jaxrs-spec-quarkus-rest-migration

Conversation

@Ignacio-Vidal

@Ignacio-Vidal Ignacio-Vidal commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Proposal to solve #24454

The quarkus library of jaxrs-spec generates for RESTEasy Classic (quarkus-resteasy) on a Quarkus version from 2021, while current Quarkus defaults to Quarkus REST. This migrates the useJakartaEe=true path and fixes the file upload binding that the old stack forced.

1. Migrate to Quarkus REST

- <artifactId>quarkus-resteasy</artifactId>
+ <artifactId>quarkus-rest</artifactId>

quarkus-rest (formerly RESTEasy Reactive) is the default REST stack in current Quarkus. One knock-on: unlike quarkus-resteasy, it does not pull bean validation in transitively, so quarkus-hibernate-validator is now declared explicitly under useBeanValidation. Without it the generated jakarta.validation imports fail to compile.

2. BOM import and version upgrade

The migration cannot happen on the currently generated version, so two coupled changes are required:

- <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
- <quarkus.platform.version>3.0.1.Final</quarkus.platform.version>
+ <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
+ <quarkus.platform.version>3.27.4.1</quarkus.platform.version>

3. File upload fixes

Two defects follow from the old stack, both fixed by the migration:

Wrong type. File form parameters were bound to InputStream, which is not a supported multipart type on Quarkus REST (the supported ones are FileUpload, Path, File, byte[], Buffer — see the Quarkus REST guide):

- public Response uploadFile(..., @FormParam(value = "file") InputStream _fileInputStream) {
+ public Response uploadFile(..., @RestForm(value = "file") FileUpload _file) {

Dropped array dimension. A type: array of format: binary properties was collapsed onto that scalar, so a multi-file upload got the same signature as a single-file one and only one file could ever be bound:

- public Response uploadMultiple(@FormParam(value = "files") InputStream filesInputStream) {
+ public Response uploadMultiple(@RestForm(value = "files") List<FileUpload> files) {

List<FileUpload> is the binding Quarkus REST provides for several files sharing one part name.

The org.jboss.resteasy.reactive types are emitted from a new libraries/quarkus/formParams.mustache rather than the shared spec/formParams.mustache, to avoid changes to thorntail, helidon, openliberty and kumuluzee libraries.

Scope: the javax path is deliberately untouched

pom.mustache forks on useJakartaEe, and the false branch is pinned to Quarkus 1.13.7 — which predates Quarkus REST entirely. That path therefore keeps RESTEasy Classic, Java 8 and its InputStream binding.

sample useJakartaEe platform result
jaxrs-spec/quarkus-security true 3.0.1 → 3.27.4.1 migrated to quarkus-rest
jaxrs-spec-microprofile-openapi-annotations unset 1.13.7 unchanged
jaxrs-spec-quarkus-mutiny unset 1.13.7 unchanged

Breaking change

Two, both on the useJakartaEe=true path:

  • Generated signatures change: InputStream _fileInputStreamFileUpload _file (the parameter name loses its suffix too). Code implementing the generated interfaces will not compile until updated.
  • The generated project now requires JDK 17 to build, since Quarkus 3.x does.

Testing

  • 2 new tests in JavaJAXRSSpecServerCodegenTest, pinning both paths:
    • testQuarkusJakartaBindsFileFormParamToFileUpload — asserts the @RestForm/FileUpload imports, the scalar FileUpload, the array List<FileUpload>, and quarkus-rest in the generated pom.xml.
    • testQuarkusJavaxKeepsResteasyClassicFileBinding — asserts the javax path still emits @FormParam/InputStream, does not gain the RESTEasy Reactive import, does not turn the array into List<InputStream>, and keeps quarkus-resteasy.
  • All three quarkus samples compile against their own poms, each on the JDK its workflow uses: jaxrs-spec/quarkus-security on Quarkus REST 3.27.4.1 with JDK 17 (matching its new workflow), and both javax samples unchanged on 1.13.7 with JDK 11.

Note jaxrs-spec-quarkus-mutiny is not listed in .github/workflows/samples-jaxrs.yaml, so CI never compiles it — I compiled it locally.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 8 files

Re-trigger cubic

The quarkus library generated for RESTEasy Classic (quarkus-resteasy), while
current Quarkus defaults to Quarkus REST. Two consequences are fixed here.

File form parameters were bound to InputStream, which Quarkus REST does not
support as a multipart type. And a `type: array` of `format: binary` properties
was collapsed onto that scalar, so a multi-file upload was generated with the
same signature as a single-file one and only one file could ever be bound.

Under useJakartaEe=true the generated project now depends on quarkus-rest and
binds file form parameters to the RESTEasy Reactive multipart types:
`@RestForm FileUpload`, or `@RestForm List<FileUpload>` when the property is an
array, which is the binding Quarkus REST provides for several files sharing one
part name. The platform moves to 3.27.4.1 (oldest supported LTS) and the BOM to
quarkus-bom, since quarkus-universe-bom was discontinued after 3.0.1 and
quarkus-rest does not exist before 3.9. quarkus-hibernate-validator is now
declared explicitly because, unlike quarkus-resteasy, quarkus-rest does not
pull bean validation in transitively.

The compiler release moves to 17 on that path, as Quarkus 3.x requires it, so
the quarkus-security sample moves from the JDK 11 samples-jaxrs workflow to
samples-jdk17.

The useJakartaEe=false path is pinned to Quarkus 1.13.7, which predates Quarkus
REST, so it keeps RESTEasy Classic, Java 8 and its InputStream binding. The
array is deliberately left scalar there: @FormParam is a string-based
annotation, so List<InputStream> is rejected at deployment with RESTEASY003875.

Refs OpenAPITools#24454
@Ignacio-Vidal
Ignacio-Vidal force-pushed the jaxrs-spec-quarkus-rest-migration branch from 6bb4578 to e70af99 Compare July 26, 2026 15:43
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.

1 participant