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

Jersey returns 400 Bad Request, logs nothing: option needed to output exceptions to the browser #5479

Open
minfrin opened this issue Nov 27, 2023 · 23 comments

Comments

@minfrin
Copy link

minfrin commented Nov 27, 2023

On an existing long standing application, after an upgrade to tomcat9 and jersey3, attempts to hit the application cause tomcat to return the following response:

<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">body {font-family:Tahoma,Ari
al,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .
line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 – Bad Request</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>
Message</b> Bad Request</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed
 request syntax, invalid request message framing, or deceptive request routing).</p><hr class="line" /><h3>Apache Tomcat/9.0.65</h3></body></html>

Jersey needs a property that can be passed to the JDK that causes Jersey to output full stacktraces out of the front door for forensic debugging.

Server side logging is impossible to configure without already knowing what the problem is.

@senivam
Copy link
Contributor

senivam commented Nov 28, 2023

which is the exact version of Jersey You've upgraded to?

@jansupol
Copy link
Contributor

jansupol commented Nov 28, 2023

You cannot use Jersey 3 with Tomcat 9, you need Tomcat 10. See https://tomcat.apache.org/download-10.cgi.

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

which is the exact version of Jersey You've upgraded to?

Jersey v2.39.1, also tried v2.40.

Sorry the original description above said jersey3, that was wrong :(

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

It looks like the point where the bad request originates is here:

There is an underlying unmarshalling problem, JAXB is broken, this bubbles up to the above. The exception is then hidden.

@jansupol
Copy link
Contributor

Is the exception printed in the Tomcat server log?

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

Unfortunately tomcat logging is of no use, because you need to know what the exception is to tell tomcat to log it, but without knowing what the exception is, you can't tell tomcat what to log.

I eventually stopped it in a debugger by breakpointing on all exceptions.

For some reason jersey was trying to use an Oracle SAX parser that wasn't being pulled in transitively.

java.lang.ClassNotFoundException: oracle.xml.jaxp.JXSAXParserFactory

Providing the missing jar above also didn't work, I don't remember why, I've been going round in circles and I've forgotten what I tried.

I tried to upgrade all of JAXB to jakarta.xml across the board, but it appears that jersey v2.41 doesn't support the jakarta version of JAXB.

Does a matrix exist anywhere of what versions of jersey is compatible with what? I am aware that breaking changes were made in the v2.x series, and I cannot for the life of me find a combination of jars (jersey, jaxb, persistence) that works.

I am stuck on tomcat9, that cannot change. I understand that means I am stuck on jersey v2.41, that cannot change. What is compatible with jersey v2.41?

@jansupol
Copy link
Contributor

Jersey 2.x works with javax namespace, so whatever jakarta jar contains javax namespace (such as jaxb 2.3.2), Jersey supports it.

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

What is confusing me horribly is that the POM of jersey-media-jaxb will tell me it depends on jakarta.xml.bind-api, but exceptions thrown by jersey are telling me that javax.xml APIs are missing.

https://eclipse-ee4j.github.io/jersey.github.io/project-info/2.41/jersey/project/jersey-media-jaxb/dependencies.html

I am now getting jersey telling me that application/xml is 415 – Unsupported Media Type in code that receives XML.

@jansupol
Copy link
Contributor

Yes, it is confusing.
First, there was Java EE 8, using javax namespace (compatible with Jersey 2.x)
Then, there was Jakarta EE 8, using jakarta prefixed jars, but inside, there is javax package. (Compatible with Jersey 2.x)
Then, there was jakarta EE 9 and 10, using jakarta prefixed jars, but inside, there is jakarta package (Not compatible with Jersey 2.x)

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

Jersey 2.x works with javax namespace, so whatever jakarta jar contains javax namespace (such as jaxb 2.3.2), Jersey supports it.

Can you confirm the exact maven coordinates of jaxb 2.3.2 if possible? this version doesn't appear to exist (v2.3.1 exists).

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

Then, there was Jakarta EE 8, using jakarta prefixed jars, but inside, there is javax package. (Compatible with Jersey 2.x)

Are there any maven coordinates for jakarta prefixed jars with javax packages inside? The inconsistent naming makes this impossible to search for.

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

This is the maven coordinates I am using right now:

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ roxanne ---
[INFO] com.example:example:war:2.0.0-SNAPSHOT
[INFO] +- javax.ws.rs:javax.ws.rs-api:jar:2.1.1:compile
[INFO] +- org.glassfish.jersey.containers:jersey-container-servlet:jar:2.41:compile
[INFO] |  +- org.glassfish.jersey.containers:jersey-container-servlet-core:jar:2.41:compile
[INFO] |  +- org.glassfish.jersey.core:jersey-common:jar:2.41:compile
[INFO] |  |  \- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] |  +- org.glassfish.jersey.core:jersey-server:jar:2.41:compile
[INFO] |  |  \- org.glassfish.jersey.core:jersey-client:jar:2.41:compile
[INFO] |  \- jakarta.ws.rs:jakarta.ws.rs-api:jar:2.1.6:compile
[INFO] +- org.glassfish.jersey.media:jersey-media-moxy:jar:2.41:compile
[INFO] |  +- org.glassfish.jersey.ext:jersey-entity-filtering:jar:2.41:compile
[INFO] |  +- jakarta.json:jakarta.json-api:jar:1.1.6:compile
[INFO] |  +- org.glassfish:jakarta.json:jar:1.1.6:compile
[INFO] |  \- org.eclipse.persistence:org.eclipse.persistence.moxy:jar:2.7.12:compile
[INFO] |     \- org.eclipse.persistence:org.eclipse.persistence.core:jar:2.7.12:compile
[INFO] |        \- org.eclipse.persistence:org.eclipse.persistence.asm:jar:9.4.0:compile
[INFO] +- org.glassfish.jersey.media:jersey-media-multipart:jar:2.41:compile
[INFO] |  \- org.jvnet.mimepull:mimepull:jar:1.9.15:compile
[INFO] +- org.glassfish.jersey.media:jersey-media-jaxb:jar:2.41:compile
[INFO] |  +- org.glassfish.hk2.external:jakarta.inject:jar:2.6.1:compile
[INFO] |  \- org.glassfish.hk2:osgi-resource-locator:jar:1.0.3:compile
[INFO] +- org.glassfish.jersey.inject:jersey-hk2:jar:2.41:compile
[INFO] |  +- org.glassfish.hk2:hk2-locator:jar:2.6.1:compile
[INFO] |  |  +- org.glassfish.hk2.external:aopalliance-repackaged:jar:2.6.1:compile
[INFO] |  |  +- org.glassfish.hk2:hk2-api:jar:2.6.1:compile
[INFO] |  |  \- org.glassfish.hk2:hk2-utils:jar:2.6.1:compile
[INFO] |  \- org.javassist:javassist:jar:3.29.2-GA:compile
[INFO] +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.1:compile
[INFO] |  \- jakarta.activation:jakarta.activation-api:jar:2.1.2:compile
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.4:compile
[INFO] |  \- org.glassfish.jaxb:jaxb-core:jar:4.0.4:compile
[INFO] |     +- org.eclipse.angus:angus-activation:jar:2.0.1:runtime
[INFO] |     +- org.glassfish.jaxb:txw2:jar:4.0.4:compile
[INFO] |     \- com.sun.istack:istack-commons-runtime:jar:4.1.2:compile
[INFO] +- javax.activation:activation:jar:1.1.1:compile
[INFO] +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] +- javax.xml.bind:jaxb-api:jar:2.3.1:compile
[INFO] |  \- javax.activation:javax.activation-api:jar:1.2.0:compile
[INFO] +- com.example:example-db:jar:2.0.0-SNAPSHOT:compile
[INFO] |  +- jakarta.persistence:jakarta.persistence-api:jar:3.1.0:compile
[INFO] |  +- jakarta.validation:jakarta.validation-api:jar:3.0.2:compile
[INFO] |  +- org.datanucleus:datanucleus-accessplatform-jakarta-rdbms:pom:6.0.6:compile
[INFO] |  |  +- org.datanucleus:jakarta.persistence:jar:3.1.0:compile
[INFO] |  |  +- org.datanucleus:datanucleus-core:jar:6.0.6:compile
[INFO] |  |  +- org.datanucleus:datanucleus-api-jakarta:jar:6.0.0-release:compile
[INFO] |  |  +- org.datanucleus:datanucleus-jakarta-query:jar:6.0.0-release:compile
[INFO] |  |  \- org.datanucleus:datanucleus-rdbms:jar:6.0.6:compile
[INFO] |  +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] |  \- com.example:example-xml:jar:2.0.1-SNAPSHOT:compile
[INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
[INFO] |  +- commons-lang:commons-lang:jar:2.6:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] \- javax.servlet:javax.servlet-api:jar:4.0.1:provided

@jansupol
Copy link
Contributor

I would recommend using what Jersey is tested with. Some dependencies (non-Jakarta) break backward compatibility without upgrading its major version.
The dependencies are best viewed in the project pom file.

@jansupol
Copy link
Contributor

Interestingly, you have both versions of JAX-B, but you are missing the implementation, I'd recommend com.sun.xml.bind:jaxb-osgi:2.3.8

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

Managed to massage things until the dependencies look like this, and I am back to the original 400 Bad Request right at the top.

java.lang.ClassNotFoundException: oracle.xml.jaxp.JXSAXParserFactory

It looks like we're missing an XML parser, but something buried in here is hard coded to look for something from Oracle.

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ example ---
[INFO] com.example:exaple:war:2.0.0-SNAPSHOT
[INFO] +- javax.ws.rs:javax.ws.rs-api:jar:2.1.1:compile
[INFO] +- org.glassfish.jersey.containers:jersey-container-servlet:jar:2.41:compile
[INFO] |  +- org.glassfish.jersey.containers:jersey-container-servlet-core:jar:2.41:compile
[INFO] |  +- org.glassfish.jersey.core:jersey-common:jar:2.41:compile
[INFO] |  |  \- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] |  +- org.glassfish.jersey.core:jersey-server:jar:2.41:compile
[INFO] |  |  \- org.glassfish.jersey.core:jersey-client:jar:2.41:compile
[INFO] |  \- jakarta.ws.rs:jakarta.ws.rs-api:jar:2.1.6:compile
[INFO] +- org.glassfish.jersey.media:jersey-media-moxy:jar:2.41:compile
[INFO] |  +- org.glassfish.jersey.ext:jersey-entity-filtering:jar:2.41:compile
[INFO] |  +- jakarta.json:jakarta.json-api:jar:1.1.6:compile
[INFO] |  +- org.glassfish:jakarta.json:jar:1.1.6:compile
[INFO] |  +- org.eclipse.persistence:org.eclipse.persistence.moxy:jar:2.7.12:compile
[INFO] |  |  \- org.eclipse.persistence:org.eclipse.persistence.core:jar:2.7.12:compile
[INFO] |  |     \- org.eclipse.persistence:org.eclipse.persistence.asm:jar:9.4.0:compile
[INFO] |  \- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:compile
[INFO] |     \- jakarta.activation:jakarta.activation-api:jar:1.2.2:compile
[INFO] +- org.glassfish.jersey.media:jersey-media-multipart:jar:2.41:compile
[INFO] |  \- org.jvnet.mimepull:mimepull:jar:1.9.15:compile
[INFO] +- org.glassfish.jersey.media:jersey-media-jaxb:jar:2.41:compile
[INFO] |  +- org.glassfish.hk2.external:jakarta.inject:jar:2.6.1:compile
[INFO] |  \- org.glassfish.hk2:osgi-resource-locator:jar:1.0.3:compile
[INFO] +- org.glassfish.jersey.inject:jersey-hk2:jar:2.41:compile
[INFO] |  +- org.glassfish.hk2:hk2-locator:jar:2.6.1:compile
[INFO] |  |  +- org.glassfish.hk2.external:aopalliance-repackaged:jar:2.6.1:compile
[INFO] |  |  +- org.glassfish.hk2:hk2-api:jar:2.6.1:compile
[INFO] |  |  \- org.glassfish.hk2:hk2-utils:jar:2.6.1:compile
[INFO] |  \- org.javassist:javassist:jar:3.29.2-GA:compile
[INFO] +- javax.activation:activation:jar:1.1.1:compile
[INFO] +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] +- com.example:example-db:jar:2.0.0-SNAPSHOT:compile
[INFO] |  +- jakarta.persistence:jakarta.persistence-api:jar:3.1.0:compile
[INFO] |  +- com.sun.xml.bind:jaxb-impl:jar:2.3.8:compile
[INFO] |  |  \- com.sun.activation:jakarta.activation:jar:1.2.2:runtime
[INFO] |  +- com.sun.xml.bind:jaxb-osgi:jar:2.3.8:compile
[INFO] |  +- jakarta.validation:jakarta.validation-api:jar:3.0.2:compile
[INFO] |  +- org.datanucleus:datanucleus-accessplatform-jakarta-rdbms:pom:6.0.6:compile
[INFO] |  |  +- org.datanucleus:jakarta.persistence:jar:3.1.0:compile
[INFO] |  |  +- org.datanucleus:datanucleus-core:jar:6.0.6:compile
[INFO] |  |  +- org.datanucleus:datanucleus-api-jakarta:jar:6.0.0-release:compile
[INFO] |  |  +- org.datanucleus:datanucleus-jakarta-query:jar:6.0.0-release:compile
[INFO] |  |  \- org.datanucleus:datanucleus-rdbms:jar:6.0.6:compile
[INFO] |  +- org.hibernate.validator:hibernate-validator:jar:6.2.5.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.4.1.Final:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.5.1:compile
[INFO] |  +- org.hibernate.validator:hibernate-validator-cdi:jar:6.2.5.Final:compile
[INFO] |  +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] |  \- com.example:example-xml:jar:1.9.0:compile
[INFO] |     \- javax.xml.bind:jaxb-api:jar:2.3.1:compile
[INFO] |        \- javax.activation:javax.activation-api:jar:1.2.0:compile
[INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
[INFO] |  +- commons-lang:commons-lang:jar:2.6:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] \- javax.servlet:javax.servlet-api:jar:4.0.1:provided

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

Chasing two bugs here.

The first is whatever in Jersey is triggering the 400 Bad Request, which may be the ClassNotFoundException, but may not be, as other ClassNotFoundExceptions are thrown making reference to classes in tomcat itself.

The second bug is a Tomcat bug, or it might be a Tomcat bug triggered by a Jersey bug, where we arrive at the following code that handles the printout of the 400 error, and there is no throwable (it is null):

https://github.com/apache/tomcat/blob/9.0.x/java/org/apache/catalina/valves/ErrorReportValve.java#L129

No throwable, and an unhandled 400 Bad Request, and we get Tomcat's generic error screen with no exception and nothing logged.

@minfrin
Copy link
Author

minfrin commented Nov 28, 2023

Found the source of the Oracle XML parser:

return isXdkFactory(parserFactory, "oracle.xml.jaxp.JXSAXParserFactory");

For some reason jersey has hard coded the name of an Oracle implementation of the class oracle.xml.jaxp.JXSAXParserFactory.

Trying to use this implementation breaks Datanucleus, which only works with Xerces.

Does jersey2 work on JDKs above java8 with all the XML code removed?

@jansupol
Copy link
Contributor

This is interesting, but it only logs information that the class was not found under FINER level logging. That does not break the runtime. You would likely see 500 if an exception would be thrown.

Under the FINER logging level, you should see the message "Starting mapping of the exception." in the server log, followed by the exception. But 400 is often a Tomcat Exception (caused by incorrect libraries in Tomcat), thrown before Jersey has an opportunity to do anything.

@Gokul-2720
Copy link

Gokul-2720 commented Feb 7, 2024

I am also experiencing same kind of problem with Jersey 3 with Tomcat 10.1.18 . Whats happening for me is when requests with empty path parameters are passed 400 bad request is thrown without any logging.
Example: for request like this error is thrown.
http://localhost:9090/proactive-api/rest/api/deviceManagement/gokul/PHONE///100///0/gokul

But for request like this are passing normally
http://localhost:9090/proactive-api/rest/user/getUser/gokul

The main thing is request is not reaching the spring layer. The request is passed from Tomcat without any changes in the path. Only logging I can see is request access log from Tomcat which just shows the request path and error code.
Weird thing is this worked fine in Jersey 2 and Tomcat 9.

@jbescos
Copy link
Member

jbescos commented Feb 7, 2024

@minfrin I am checking this: https://github.com/gluser1357/jerseyissues/tree/issue-5404-crosscontext

It is working in latest 3.1 (I am testing with the compiled Jersey 3.1 branch that has the version 3.1.99-SNAPSHOT)

$ curl -v http://localhost:8080/jerseyissue-5404/tests/forward
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /jerseyissue-5404/tests/forward HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 
< Content-Type: text/plain
< Content-Length: 17
< Date: Wed, 07 Feb 2024 13:26:32 GMT
< 
* Connection #0 to host localhost left intact
MyAPI /tests/a ok

@Gokul-2720
Copy link

Gokul-2720 commented Feb 8, 2024

This is what I am using in my project
<org.springframework.version>6.1.2</org.springframework.version> <spring.security.version>6.2.1</spring.security.version> <jersey.version>3.1.5</jersey.version>

This is the latest available jersey version in maven repository.

This is my configuration in web.xml
<servlet> <servlet-name>RestService</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.tarshan.gokul.proactive.rest</param-value> </init-param> <init-param> <param-name>jersey.config.jsonFeature.jackson.jaxb.annotationProcessing</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>jersey.config.server.modelValidation</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>RestService</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>

And this is what I am getting in Tomcat localhost access log

127.0.0.1 - - [07/Feb/2024:17:23:06 +0530] "GET /proactive-api/rest/api/deviceManagement/gokul/PHONE///100///0/gokul HTTP/1.1" 400 763

The error I'm getting in Postman is
<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 – Bad Request</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).</p><hr class="line" /><h3>Apache Tomcat/10.1.18</h3></body></html>

Other than these, I dont have any trace or reason for this behaviour. Could you please try testing with // [Consecutive slashes]
in your request path like this:
/jerseyissue-5404/tests//forward
I am passing these consecutive slashes because those are empty path parameters.

@jbescos
Copy link
Member

jbescos commented Feb 8, 2024

I am getting 404 in Jersey instead of 400, in this stacktrace:

Daemon Thread [http-nio-8080-exec-16] (Suspended)	
	org.glassfish.jersey.server.ServerRuntime$1.run() line: 258	
	org.glassfish.jersey.internal.Errors$1.call() line: 248	
	org.glassfish.jersey.internal.Errors$1.call() line: 244	
	org.glassfish.jersey.internal.Errors.process(java.util.concurrent.Callable<T>, boolean) line: 292	
	org.glassfish.jersey.internal.Errors.process(org.glassfish.jersey.internal.util.Producer<T>, boolean) line: 274	
	org.glassfish.jersey.internal.Errors.process(java.lang.Runnable) line: 244	
	org.glassfish.jersey.inject.hk2.Hk2RequestScope(org.glassfish.jersey.process.internal.RequestScope).runInScope(org.glassfish.jersey.process.internal.RequestContext, java.lang.Runnable) line: 265	
	org.glassfish.jersey.server.ServerRuntime.process(org.glassfish.jersey.server.ContainerRequest) line: 240	
	org.glassfish.jersey.server.ApplicationHandler.handle(org.glassfish.jersey.server.ContainerRequest) line: 697	
	org.glassfish.jersey.servlet.WebComponent.serviceImpl(java.net.URI, java.net.URI, jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse) line: 394	
	org.glassfish.jersey.servlet.WebComponent.service(java.net.URI, java.net.URI, jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse) line: 346	
	org.glassfish.jersey.servlet.ServletContainer.service(java.net.URI, java.net.URI, jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse) line: 357	
	org.glassfish.jersey.servlet.ServletContainer.service(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse) line: 311	
	org.glassfish.jersey.servlet.ServletContainer.service(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse) line: 205	
	org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse) line: 205	
	org.apache.catalina.core.ApplicationFilterChain.doFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse) line: 149	
	org.apache.tomcat.websocket.server.WsFilter.doFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse, jakarta.servlet.FilterChain) line: 51	
	org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse) line: 174	
	org.apache.catalina.core.ApplicationFilterChain.doFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse) line: 149	
	org.apache.catalina.core.StandardWrapperValve.invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) line: 166	
	org.apache.catalina.core.StandardContextValve.invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) line: 90	
	org.apache.catalina.authenticator.NonLoginAuthenticator(org.apache.catalina.authenticator.AuthenticatorBase).invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) line: 482	
	org.apache.catalina.core.StandardHostValve.invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) line: 115	
	org.apache.catalina.valves.ErrorReportValve.invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) line: 93	
	org.apache.catalina.valves.AccessLogValve(org.apache.catalina.valves.AbstractAccessLogValve).invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) line: 676	
	org.apache.catalina.core.StandardEngineValve.invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) line: 74	
	org.apache.catalina.connector.CoyoteAdapter.service(org.apache.coyote.Request, org.apache.coyote.Response) line: 341	
	org.apache.coyote.http11.Http11Processor.service(org.apache.tomcat.util.net.SocketWrapperBase<?>) line: 390	
	org.apache.coyote.http11.Http11Processor(org.apache.coyote.AbstractProcessorLight).process(org.apache.tomcat.util.net.SocketWrapperBase<?>, org.apache.tomcat.util.net.SocketEvent) line: 63	
	org.apache.coyote.AbstractProtocol$ConnectionHandler<S>.process(org.apache.tomcat.util.net.SocketWrapperBase<S>, org.apache.tomcat.util.net.SocketEvent) line: 894	
	org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun() line: 1741	
	org.apache.tomcat.util.net.NioEndpoint$SocketProcessor(org.apache.tomcat.util.net.SocketProcessorBase<S>).run() line: 52	
	org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker) line: 1191	
	org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run() line: 659	
	org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run() line: 61	
	org.apache.tomcat.util.threads.TaskThread(java.lang.Thread).run() line: 833	

With this resource method:

    @GET
    @Path("paths/{a}/{b}/c")
    public static Response paths(@PathParam("a") String a, @PathParam("b") String b) throws Exception {
        Thread.dumpStack();
        System.out.println("tests/paths/{a}/{b}/c");
        return Response.ok().entity("paths/" + a + "/" + b + "/c").build();
    }
$ curl -v http://localhost:8080/jerseyissue-5404/tests/paths///c
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /jerseyissue-5404/tests/paths///c HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 713
< Date: Thu, 08 Feb 2024 06:14:04 GMT
< 
* Connection #0 to host localhost left intact
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Not Found</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/10.1.8</h3></body></html>
$ curl -v http://localhost:8080/jerseyissue-5404/tests/paths/a/b/c
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /jerseyissue-5404/tests/paths/a/b/c HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 
< Content-Type: text/plain
< Content-Length: 11
< Date: Thu, 08 Feb 2024 06:14:27 GMT
< 
* Connection #0 to host localhost left intact
paths/a/b/c

@Gokul-2720 Could you share a simple app that throws 400?. I am not able to reproduce your issue.

@Gokul-2720
Copy link

I dont know what is happening here, If I provide values for all the path parameters like you did, I get 200 response code and API is returning the response properly.

http://localhost:9090/proactive-api/rest/api/deviceManagement/gokul/PHONE/a/b/100/c/d/0/gokul

Tomcat access log:
127.0.0.1 - - [08/Feb/2024:12:50:54 +0530] "GET /proactive-api/rest/api/deviceManagement/gokul/PHONE/a/b/100/c/d/0/gokul HTTP/1.1" 200 46

But when the path parameters are empty I'm getting 400 bad request.

Actually I'm working on a complex enterprise application upgrade. Let me check whether I can provide any simple application with you.

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

No branches or pull requests

5 participants