-
Notifications
You must be signed in to change notification settings - Fork 565
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
API Calls failing with exception - Entity has already been requested. Entity cannot be requested multiple times #8349
Comments
Hi Team, we have an update to share. As part of debugging from our side, we removed all the manual application addition and let Helidon discover and register the Jax-Rs Apps. Seems that fixed this issue for now (undergoing further testing). But still we would like to know what causes this when we manually add the applications. |
Thank you for your work on this! So you have your app working now, right? Do not worry, we will investigate this and will keep you posted on our findings :-) |
Yes David, as per our initial testing, the application is working as expected. I will keep you posted if we face any challenges. As of now, this issue is not a blocker for us. Thanks for all your help. I bet you will get to the bottom of this. We look forward to your findings. |
Hello, We are using Heldion 4.0.2 and running into same issue. Is there any fix out yet? |
This issue is triggered when there is more than one instance of If the request contains an entity payload and the first service does not match because the request is for a different JaxRs application, then the next service in the chain fails as the first one has already invoked E.g. public class Main {
public static void main(String[] args) {
Server.builder()
.addApplication(App1.class)
.addApplication(App2.class)
.build()
.start();
}
@ApplicationPath("/")
@ApplicationScoped
public static class App1 extends Application {
@Override
public Set<Class<?>> getClasses() {
return Set.of(Resource.class);
}
@Path("/app1")
public static class Resource {
@GET
public String get() {
return "OK";
}
}
}
@ApplicationPath("/")
@ApplicationScoped
public static class App2 extends Application {
@Override
public Set<Class<?>> getClasses() {
return Set.of(Resource.class);
}
@Path("/app2")
public static class Resource {
@GET
public String get() {
return "OK";
}
}
}
} curl -d "{}" http://localhost:8080/app2 Server logs:
When Helidon discovers the classes, if there is no application it aggregates all resources into a single synthetic application, in this case you won't run into this issue. However, if there is more than one application, then the issue still exist. io.helidon.Main.main(args); Note that if the application classes are not annotated with |
Potential fix: diff --git a/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsService.java b/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsService.java
index e268d372f0..7eaffedaf2 100644
--- a/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsService.java
+++ b/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsService.java
@@ -17,6 +17,7 @@
package io.helidon.microprofile.server;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.lang.System.Logger.Level;
@@ -181,11 +182,19 @@ class JaxRsService implements HttpService {
context.supply(ServerRequest.class, () -> req);
context.supply(ServerResponse.class, () -> res);
+ // request entity stream can be only consumed once
+ // store it in the request context to ensure a single call to req.content().inputStream()
+ InputStream entityStream = context.get(InputStream.class).orElseGet(() -> {
+ InputStream is = req.content().inputStream();
+ context.register(is);
+ return is;
+ });
+
// call doHandle in active context
- Contexts.runInContext(context, () -> doHandle(context, req, res));
+ Contexts.runInContext(context, () -> doHandle(context, req, res, entityStream));
}
- private void doHandle(Context ctx, ServerRequest req, ServerResponse res) {
+ private void doHandle(Context ctx, ServerRequest req, ServerResponse res, InputStream is) {
BaseUriRequestUri uris = BaseUriRequestUri.resolve(req);
ContainerRequest requestContext = new ContainerRequest(uris.baseUri,
uris.requestUri,
@@ -205,7 +214,7 @@ class JaxRsService implements HttpService {
JaxRsResponseWriter writer = new JaxRsResponseWriter(res);
requestContext.setWriter(writer);
- requestContext.setEntityStream(req.content().inputStream());
+ requestContext.setEntityStream(is);
requestContext.setProperty("io.helidon.jaxrs.remote-host", req.remotePeer().host());
requestContext.setProperty("io.helidon.jaxrs.remote-port", req.remotePeer().port());
requestContext.setRequestScopedInitializer(ij -> { |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Reproduced in an integration test on |
There is a new test added in the PR that failed before the fix. |
We have a set of API endpoints exposed in our helidon application and after upgrading to Helidon 4, it fails with the above exception
Environment Details
Problem Description
We are trying to upgrade our Helidon application from v3 to v4. After the upgrade, requests to the API endpoints are failing with the exception "Entity has already been requested. Entity cannot be requested multiple times" (refer attached stack trace). The exception occurs before the logic of the endpoint comes into picture and it seems to come from the Helidon server itself.
Following is the full stack trace.
Since we have a bunch of teams owning different API endpoints, we have consolidated them into different Applications. We have a Main function that adds these applications and starts the server as shown in the code-block below.
I have found that the issue does not affect the endpoints of the application that gets added to the server first. For the rest of the applications, the requests are met with the mentioned exception. I have compared the different applications and the corresponding resource classes and did not find any major differences between them.
Steps to reproduce
The text was updated successfully, but these errors were encountered: