Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jakarta RESTful Web Services 3.1 Multipart support does not work #38980

Closed
aaronjwhiteside opened this issue Feb 23, 2024 · 7 comments
Closed
Labels
area/resteasy-classic kind/bug Something isn't working triage/needs-reproducer We are waiting for a reproducer.

Comments

@aaronjwhiteside
Copy link

Describe the bug

I'm unable to make the multipart examples from the resteasy documentation (https://docs.jboss.org/resteasy/docs/6.2.6.Final/userguide/html/ch26.html#entity_part) work.

I'm using the quarkus-resteasy-reactive but the problem persists with the normal quarkus-resteasy dependency.

Expected behavior

No runtime exceptions.

Actual behavior

    java.lang.RuntimeException: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor#setupEndpoints threw an exception: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:328)
        at io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor.setupEndpoints(ResteasyReactiveProcessor.java:661)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:849)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:256)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at java.base/java.lang.Thread.run(Thread.java:1583)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
    Caused by: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:777)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:417)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:295)
        ... 10 more
    Caused by: java.lang.RuntimeException: Could not create converter for jakarta.ws.rs.core.EntityPart for method java.util.List<jakarta.ws.rs.core.EntityPart> injected(java.lang.String string, jakarta.ws.rs.core.EntityPart entityPart, java.io.InputStream in) on class com.velostone.modules.dp.web.EvidenceApiImpl of type FORM
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:372)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:98)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.extractParameterInfo(EndpointIndexer.java:1428)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:594)
        ... 12 more
    Caused by: java.lang.RuntimeException: Failed to find converter for jakarta.ws.rs.core.EntityPart
        at org.jboss.resteasy.reactive.server.processor.generation.converters.GeneratedConverterIndexerExtension.extractConverterImpl(GeneratedConverterIndexerExtension.java:106)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.extractConverter(ServerEndpointIndexer.java:578)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:368)
        ... 15 more

    Caused by: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor#setupEndpoints threw an exception: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:328)
        at io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor.setupEndpoints(ResteasyReactiveProcessor.java:661)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:849)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:256)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at java.base/java.lang.Thread.run(Thread.java:1583)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
    Caused by: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:777)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:417)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:295)
        ... 10 more
    Caused by: java.lang.RuntimeException: Could not create converter for jakarta.ws.rs.core.EntityPart for method java.util.List<jakarta.ws.rs.core.EntityPart> injected(java.lang.String string, jakarta.ws.rs.core.EntityPart entityPart, java.io.InputStream in) on class com.velostone.modules.dp.web.EvidenceApiImpl of type FORM
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:372)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:98)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.extractParameterInfo(EndpointIndexer.java:1428)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:594)
        ... 12 more
    Caused by: java.lang.RuntimeException: Failed to find converter for jakarta.ws.rs.core.EntityPart
        at org.jboss.resteasy.reactive.server.processor.generation.converters.GeneratedConverterIndexerExtension.extractConverterImpl(GeneratedConverterIndexerExtension.java:106)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.extractConverter(ServerEndpointIndexer.java:578)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:368)
        ... 15 more

    Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor#setupEndpoints threw an exception: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:328)
        at io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor.setupEndpoints(ResteasyReactiveProcessor.java:661)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:849)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:256)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at java.base/java.lang.Thread.run(Thread.java:1583)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
    Caused by: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:777)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:417)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:295)
        ... 10 more
    Caused by: java.lang.RuntimeException: Could not create converter for jakarta.ws.rs.core.EntityPart for method java.util.List<jakarta.ws.rs.core.EntityPart> injected(java.lang.String string, jakarta.ws.rs.core.EntityPart entityPart, java.io.InputStream in) on class com.velostone.modules.dp.web.EvidenceApiImpl of type FORM
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:372)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:98)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.extractParameterInfo(EndpointIndexer.java:1428)
        at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:594)
        ... 12 more
    Caused by: java.lang.RuntimeException: Failed to find converter for jakarta.ws.rs.core.EntityPart
        at org.jboss.resteasy.reactive.server.processor.generation.converters.GeneratedConverterIndexerExtension.extractConverterImpl(GeneratedConverterIndexerExtension.java:106)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.extractConverter(ServerEndpointIndexer.java:578)
        at org.jboss.resteasy.reactive.server.processor.ServerEndpointIndexer.handleOtherParam(ServerEndpointIndexer.java:368)
        ... 15 more

    Caused by: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'

    Caused by: java.lang.RuntimeException: Failed to process method 'com.velostone.modules.dp.web.EvidenceApiImpl#injected'

    Caused by: java.lang.RuntimeException: Could not create converter for jakarta.ws.rs.core.EntityPart for method java.util.List<jakarta.ws.rs.core.EntityPart> injected(java.lang.String string, jakarta.ws.rs.core.EntityPart entityPart, java.io.InputStream in) on class com.velostone.modules.dp.web.EvidenceApiImpl of type FORM

    Caused by: java.lang.RuntimeException: Failed to find converter for jakarta.ws.rs.core.EntityPart

How to Reproduce?

Given an example, taken from the RESTEasy documentation: https://docs.jboss.org/resteasy/docs/6.2.6.Final/userguide/html/ch26.html#entity_part

   @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.MULTIPART_FORM_DATA)
    @Path("/injected")
    fun injected(
        @FormParam("content") string: String,
        @FormParam("content") entityPart: EntityPart,
        @FormParam("content") `in`: InputStream
    ): List<EntityPart> {
        val multipart: MutableList<EntityPart> = ArrayList()
        multipart.add(
            EntityPart.withName("received-entity-part")
                .content(entityPart.getContent(String::class.java))
                .mediaType(entityPart.mediaType)
                .fileName(entityPart.fileName.orElse(null))
                .build()
        )
        multipart.add(
            EntityPart.withName("received-input-stream")
                .content(`in`.bufferedReader().use { it.readText() })
                .mediaType(MediaType.APPLICATION_OCTET_STREAM_TYPE)
                .build()
        )
        multipart.add(
            EntityPart.withName("received-string")
                .content(string)
                .mediaType(MediaType.TEXT_PLAIN_TYPE)
                .build()
        )
        return multipart
    }

Output of uname -a or ver

Darwin 002646-mac.local 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 arm64

Output of java -version

openjdk 21.0.1 2023-10-17 LTS OpenJDK Runtime Environment Zulu21.30+15-CA (build 21.0.1+12-LTS) OpenJDK 64-Bit Server VM Zulu21.30+15-CA (build 21.0.1+12-LTS, mixed mode, sharing)

Quarkus version or git rev

3.7.3

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 8.5

Additional information

No response

@aaronjwhiteside aaronjwhiteside added the kind/bug Something isn't working label Feb 23, 2024
@aaronjwhiteside aaronjwhiteside changed the title JAX-RS 3.1 Multipart support does not work Jakarta RESTful Web Services 3.1 Multipart support does not work Feb 23, 2024
@geoand
Copy link
Contributor

geoand commented Feb 26, 2024

RESTEasy Reactive and RESTEasy Classic differ in their support for Multipart, so anything you see in the latter's docs won't work in the former.

I'll cc @jamezp for the RESTEasy Classic part of this

@jamezp
Copy link
Contributor

jamezp commented Feb 26, 2024

This should work in RESTEasy already. There is an example standalone application for it https://github.com/resteasy/resteasy-examples/blob/main/standalone-multipart/src/main/java/dev/resteasy/examples/multipart/UploadResource.java#L49. My assumption would be that RESTEasy Reactive needs a MessageBodyWriter and MessageBodyReader for the EntityPart.

@geoand
Copy link
Contributor

geoand commented Feb 26, 2024

@jamezp reading the issue, OP mentions that it does not work in RESTEasy Classic

@jamezp
Copy link
Contributor

jamezp commented Feb 26, 2024

@geoand Hmm... ...the stack trace looks like RESTEasy Reactive to me. I guess we'd need to see a reproducer. I know for sure it works in that SeBootstrap example and in WildFly.

@geoand
Copy link
Contributor

geoand commented Feb 26, 2024

Yes, but OP also mentioned that it does work with RESTEasy Classic either, or at least that's how I parsed it

@jamezp
Copy link
Contributor

jamezp commented Feb 26, 2024

Okay, I guess I'd need a reproducer then. All I can say is I know that example works :) The only reason I could think of it wouldn't work is if the org.jboss.resteasy:resteasy-multipart-provider dependency is missing.

@geoand geoand added the triage/needs-reproducer We are waiting for a reproducer. label Feb 27, 2024
@geoand
Copy link
Contributor

geoand commented Apr 2, 2024

Closing as we never got a reproducer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/resteasy-classic kind/bug Something isn't working triage/needs-reproducer We are waiting for a reproducer.
Projects
None yet
Development

No branches or pull requests

3 participants