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

Weblogic 12.2.1 and GraphQL Java Servlet #61

Closed
briancullen opened this issue Jan 12, 2018 · 7 comments

Comments

@briancullen
Copy link
Contributor

commented Jan 12, 2018

Hello I'm trying to deploy a GraphQL servlet version 4.7.0 within a Spring MVC war that will be deployed onto Weblogic 12.2.1 and whenever I try and do a request with a content type of application-json I get the following error.

Bad POST request: parsing failed com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
at [Source: weblogic.servlet.internal.ServletInputStreamImpl@14b82135; line: 1, column: 0]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:255)
at com.fasterxml.jackson.databind.ObjectReader._initForReading(ObjectReader.java:361)
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1561)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1166)
at graphql.servlet.GraphQLServlet.lambda$new$1(GraphQLServlet.java:197)
at graphql.servlet.GraphQLServlet.doRequest(GraphQLServlet.java:255)

I think I have tracked the problem down to the post handler, specifically the part that deals with requests that are not multipart requests (starts on line 188 in the version I have). This code checks that marking is supported by the input stream and if it isn't wraps it in a BufferedInputStream so that the isBatchedQuery method can "peek" ahead at the request body and then reset back to the start of the input for the parser.

The input stream class at this stage is an implementation of ServletInputStream which is implemented different for different application containers. Most containers, like Tomcat, do not implement marking on their implementation so it will be wrapped by a BufferedInputStream. Unfortunately Weblogic does implement these methods on it's version and so will not be wrapped.

This would not cause a problem apart from the line of code where the input stream is marked, as shown below, in the isBatchedQuery method (line 449).

inputStream.mark(0);

According to the Java API the parameter (in this case zero) indicates the maximum number of bytes that can be read before the mark becomes invalid. So technically this is saying that the mark becomes invalid the moment any data is read from it. This doesn't cause an issue with BufferedInputStreams as this parameter is ignored (in fact it seems to be ignored by a lot of implementations I have seen) but the weblogic implementation does use the value passed to it. This means that when reset is called at the end of the isBatchedQuery method the input stream is not actually reset and the parsing then fails. In my case I get a no content error because there is less than 128 characters in the body so the parser gets no input.

The quick solution as far as I can see is to rewrite the method as shown in the snippet below. The difference being that we set the maximum number of characters for the mark to equal the size of the buffer we are about to read in. In that way the reset method will be able to do it's job and the parser will find the expected input.

        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[128];
        int length;

        inputStream.mark(128);
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
            String chunk = result.toString();

Does this seem like a reasonable solution to the problem I'm having or have I missed something? I can create a pull request for this (although I'm away for the next week) but I thought it best to raise an issue first and ensure that this is the best approach.

@apottere

This comment has been minimized.

Copy link
Contributor

commented Jan 12, 2018

This seems fine to me, I didn't actually write the batch detection code so I'm not very familiar with how it works though. A PR would be great!

@briancullen

This comment has been minimized.

Copy link
Contributor Author

commented Jan 13, 2018

Ok, as I mentioned I’m away from my computer next week but I’ll get a PR up once I’m back.

@briancullen

This comment has been minimized.

Copy link
Contributor Author

commented Feb 1, 2018

I have put in a pull request to address this issue (see reference above). If someone has some time to look at the request I would really appreciate it.

@ronald-d-rogers

This comment has been minimized.

Copy link
Contributor

commented Feb 9, 2018

Yup this looks like my bad, I misunderstood how the mark method works.

@briancullen

This comment has been minimized.

Copy link
Contributor Author

commented Feb 28, 2018

Just to try and keep this alive. If we are happy that this is an issue would it be possible to review and hopefully merge the associated fix?

@baens

This comment has been minimized.

Copy link

commented Mar 6, 2018

+1 on this. I was running the servlet with the grizzly embedded web server and this has the same issues.

The related PR fixes those issues.

@oliemansm

This comment has been minimized.

Copy link
Member

commented Aug 25, 2018

Closing since PR #62 fixed this issue

@oliemansm oliemansm closed this Aug 25, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.