1

I'm developing a Java EE web application running on WildFly 18, and Angular on the front end. All the HTTP calls from Angular to Wildfly are POSTs. The application works fine, but once a month, when I start it, I cannot use it because Wildfly rejects the request saying that the HTTP method POST is not supported by this URL (see error below on browser console). Just to make sure is not Angular, I made the POST call from a Java program, and got the same error.

The solution is to close everything and restart, sometimes more than once. Why does this happen and how to fix this? The big problem is that this may happen in production.

visualcode/rest/getbropr:1 Failed to load resource: the server responded with a status of 405 (Method Not Allowed) main.js:1127 HttpErrorResponse error: "Error HTTP method POST is not supported by this URL" headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ} message: "Http failure response for http://localhost:4400/visualcode/rest/getbropr: 405 Method Not Allowed" name: "HttpErrorResponse" ok: false status: 405 statusText: "Method Not Allowed" url: "http://localhost:4400/visualcode/rest/getbropr"

UPDATE

This happened to me in two different machines with identical Wildfly configuration, so it must be something on how JAX-RS or any other related component is set up.

UPDATE 2

I got the error and this is the server log:

11:46:17,306 DEBUG [io.undertow.request] (default I/O-12) Matched prefix path /visualcode for path /visualcode/rest/getbropr
11:46:17,306 DEBUG [io.undertow.request.security] (default task-1) Attempting to authenticate /visualcode/rest/getbropr, authentication required: false
11:46:17,306 DEBUG [io.undertow.request.security] (default task-1) Authentication outcome was NOT_ATTEMPTED with method io.undertow.security.impl.CachedAuthenticatedSessionMechanism@2d8f2c0a for /visualcode/rest/getbropr
11:46:17,306 DEBUG [io.undertow.request.security] (default task-1) Authentication result was ATTEMPTED for /visualcode/rest/getbropr
11:46:17,307 INFO  [io.undertow.request.dump] (default task-1) 
----------------------------REQUEST---------------------------
               URI=/visualcode/rest/getbropr
 characterEncoding=null
     contentLength=2
       contentType=[application/json]
            cookie=_ga=GA1.1.1378850711.1587329434
            header=accept=application/json, text/plain, */*
            header=accept-language=en-US,en;q=0.9,es;q=0.8
            header=accept-encoding=gzip, deflate, br
            header=sec-fetch-mode=cors
            header=origin=http://localhost:4400
            header=user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
            header=sec-fetch-dest=empty
            header=connection=close
            header=sec-fetch-site=same-origin
            header=cookie=_ga=GA1.1.1378850711.1587329434
            header=content-type=application/json
            header=content-length=2
            header=referer=http://localhost:4400/login
            header=host=localhost:8080
            locale=[en_US, en, es]
            method=POST
          protocol=HTTP/1.1
       queryString=
        remoteAddr=/127.0.0.1:51323
        remoteHost=kubernetes.docker.internal
            scheme=http
              host=localhost:8080
        serverPort=8080
          isSecure=false
--------------------------RESPONSE--------------------------
     contentLength=104
       contentType=text/html;charset=UTF-8
            header=Connection=close
            header=Content-Type=text/html;charset=UTF-8
            header=Content-Length=104
            header=Date=Thu, 09 Jul 2020 15:46:17 GMT
            status=405

==============================================================

And this is the code that (sometimes) fails:

@Path("/")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public class LoginService {
    
    @Inject
    private SomeBean bean;
    
    @Context
    private HttpServletRequest httpRequest;

    @POST
    @Path("/getbropr")
    public Response getBrowserProperties() {
          // process response
    }
ps0604
  • 1,227
  • 23
  • 133
  • 330
  • Have you check Wildfly logs? Does the "getbropr" method in your server code send 405 somewhere? Without more info it's a bit hard to guess what the problem could be. – assylias Jun 22 '20 at 14:36
  • can you check out the headers for me? is there any header parameter required in order for the `POST` request to be run? for instance, if you need a `SESSIONID` on the header to make a post request we need to make sure this parameter is not `expired`. – Phill Alexakis Jun 22 '20 at 14:57
  • @PhillAlexakis I'll check the SESSIONID the next time this happens, is very difficult to reproduce. – ps0604 Jun 23 '20 at 10:28
  • i suggest you capture a snapshot of the state that runs okay, headers responses etc, and also when it crashes (programmatically), this is how i declare the method in spring: `@RequestMapping(value="/myendpoint",method = RequestMethod.GET)` if i `POST` to that endpoint i'll get `HTTP method POST is not supported by this URL` , if sometimes it runs and sometimes not, this means there is something else going on, you need to check every input output ( `HttpRequest` , `HttpResponse` ). – Phill Alexakis Jun 23 '20 at 12:25

1 Answers1

2

At the moment I did not find any similar issue in his issue tracker. I have also not had a similar problem with wildfly 17 and 19.

So, the first Thing I suggest you check to solve the problem is to carry out the following checks and collect certain information to help:

  1. first check the wildfly logs and change them in trace or debug mode
  2. Second verify that you are not going through a balancer, reverse proxy, firewall or any intermediary that may be the issuer of the response that you are seeing in the client
  3. Log the call made including (url, headers, http method, parameters and body) and the same data of the received answer, or try if it is possible to reproduce the call with a visual tool like postman or by command line with a command like curl.

With these tests, you can first determine the true origin of the service response. sometimes bad configurations in balancers, networks, etc. can cause that the calls do not arrive at the destination and the one that answers is another service.

It is useful to check the headers that are included, since traces are sometimes found. Or the format or message in the body of the response, which can be another indication to determine the origin.

If we have confirmed that the origin is the service, it is convenient for us to review the traces from the moment it began to fail backwards. There may be clues to a fault or a mishandled exception when a fault occurs internally. For example if we are using Resteasy (jax-rs) with wildfly (which is quite common), an exception thrown wrong when there is an internal error (database not available, internal services unreachable, etc.) or an exception mapper is wrong... it can cause an incorrect message and error code to be printed which would be a distraction to solve the real problem (it would not be something very common that happens but it is a point to keep in mind and reviewing the logs can help here).

if after analyzing the response, confirming its origin, analyzing the traces and exceptions, your problem persists ... I suggest you provide greater detail of your application in this thread (for example, java version, libs, implement direct with servlet or resteasy?, authentication?, etc) ... any information you can provide such as the trace or a small demo with similar characteristics that can be used to reproduce the problem will be welcome to help you solve the problem.

Update:

Knowing that you are running the service locally, I ask you to configure Wildfly to print the call and its parameters in your logs. Wildfly uses undertow as engine so please add a filter to your undertow configuration to log your request. Add to your standalone.xml -> subsystem "undertow" the following configuration:

<subsystem xmlns = "urn:jboss:domain: undertow: 3.0">
         <server name = "default-server">
             <host name = "default-host" alias = "localhost">
...
                 <filter-ref name = "request-logger" />
             </host>
         </server>
         <filters>
...
             <filter name = "request-logger" module = "io.undertow.core"
               class-name = "io.undertow.server.handlers.RequestDumpingHandler" />
         </filters>
     </subsystem>

Alternatively, you can change your xml configuration with jboss-cli.sh with this script:

$WILDFLY_HOME/bin/jboss-cli.sh --connect --file=script.cli

script.cli file:

batch
/subsystem=undertow/configuration=filter/custom-filter=request-logging-filter:add(class-name=io.undertow.server.handlers.RequestDumpingHandler, module=io.undertow.core)
/subsystem=undertow/server=default-server/host=default-host/filter-ref=request-logging-filter:add
run-batch

Any call that reaches undertow through the open port should log the data received in your logs and that will help to know if the call reaches the wildfly and be able to trace the problem. Debug logs will also be welcome later if the call actually reaches wildfly.

On the other hand, have you tested if the problem persists in Wildfly 20? Updating the wildfly between 18-20 is relatively simple.

Update 2:

The request looks good, so I suggest you check the startup logs. Seems to be a race condition at start, Wildfly runs many tasks simultaneously to get started ASAP.

Typically, when you have duplicate configuration files in classpath or startup codes, it can lead to unexpected behavior, so comparing logs is helpful. Check that you only have a web.xml and file descriptors in your .war file.

Hope I can helps

Ariel Carrera
  • 5,113
  • 25
  • 36
  • Ariel, unfortunately this problem is very difficult to reproduce. I can tell you that the server log doesn't have anything, but is not in debug mode so all I can do at this point is to turn the debug mode on. Everything runs in my laptop, so there's nothing strange like balancers or network configurations.Also, there are no exceptions thrown anywhere, as I don't get the POST request at the server side. – ps0604 Jun 23 '20 at 10:34
  • Note: when I say `I don't get the POST request at the server side` I mean that I don't get it in my code. Wildfly is getting it as it sends back the error `405`. – ps0604 Jun 23 '20 at 15:18
  • @ps0604, I update my answer to keep track of the problem, try adding the filter in undertow and see what happens when the problem occurs in the logs, if the request actually arrives at wildfly. Also try the latest version of wildfly (20) which usually has its modules updated and fixes, it should not be too difficult to update. – Ariel Carrera Jun 23 '20 at 19:30
  • Thanks, I added undertow and can see the requests and responses in the server log. Now I'm more prepared when the problem happens again. I accepted your answer as I don't know when the error will happen, but I may ask you a question in the future depending on how it goes. – ps0604 Jun 23 '20 at 20:56
  • let me know if it happens again and I can help you. regards! – Ariel Carrera Jun 24 '20 at 00:16
  • @ps0604 I added an "Update 2" section, check it. – Ariel Carrera Jul 09 '20 at 22:39
  • I have only one web.xml and configuration files, any other ideas? – ps0604 Jul 10 '20 at 11:07
  • Compare your logs... check what is the difference during startup. Compare your war files contents to dismiss a conflict during build time. How are you starting your server? (ide? embedded test? command line?) How are you deploying your application? (Ide plugin? Maven plugin? Jboss-cli? Console? Command-line?) – Ariel Carrera Jul 10 '20 at 14:34
  • this happens both embedded in Eclipse and standalone, and the deployment happens automatically from Eclipse. All this works fine with the exception of one or two times a month when I get error `405`. Next time I'll compare the logs to see any differences during startup. – ps0604 Jul 10 '20 at 15:27
  • I coudn't find any differences or errors in the logs... – ps0604 Jul 10 '20 at 15:40
  • It's strange there isn't any difference (maybe at debug level you can find the cause). A practice that I usually do with Eclipse/Maven to avoid some conflicts during build time, is to isolate the Eclipse build target from the one used by command line (with a maven profile activated in Eclipse). – Ariel Carrera Jul 10 '20 at 21:13
  • this kind of problems, usually gives us a headache to solve. Sometimes if the server is abruptly shutdown (closed), the temporary and data folders are inconsistent and similar problems can occur and it is necessary to clean the temporary and data folders before initializing it, for example. – Ariel Carrera Jul 10 '20 at 21:20
  • I’m logging at debug level and cannot tell the difference. What are these temporary folders? – ps0604 Jul 10 '20 at 21:31
  • Assuming you start your server in standalone mode, /standalone/tmp contains temporary files and standalone/data contains files written during startup and their lifecycle (deployments files, xa transactions, jms data, etc) – Ariel Carrera Jul 10 '20 at 22:19
  • Ok, I didn't try that, next time I will delete the `tmp` folder, the `data` folder can be deleted as well? – ps0604 Jul 10 '20 at 22:31
  • In development, yes... in production depends on what kind of things your application do (jms, transactions, persistent cache, etc will be affected) – Ariel Carrera Jul 11 '20 at 02:20
  • Thanks, next time I get the error I will try deleting the folders – ps0604 Jul 11 '20 at 02:33
  • Ariel, deleting the `tmp` and `data` folders didn't work, any other ideas? thanks – ps0604 Jul 20 '20 at 10:49
  • hi @ps0604, I still suspect that it may be a configuration issue due to multiple registration of some component or something like this... if you upload a demo project to github that allows you to reproduce the problem with the steps necessary to reproduce it, I can try it on my laptop – Ariel Carrera Jul 29 '20 at 23:38
  • Ariel, I'm getting this in the log when I get the 405 error, does it mean anything to you? `08:32:03,023 DEBUG [io.undertow.request.security] (default task-1) Attempting to authenticate /visualcode/rest/getbropr, authentication required: false 08:32:03,024 DEBUG [io.undertow.request.security] (default task-1) Authentication outcome was NOT_ATTEMPTED with method io.undertow.security.impl.CachedAuthenticatedSessionMechanism@5437a4b1 for /visualcode/rest/getbropr 08:32:03,024 DEBUG [io.undertow.request.security] (default task-1) Authentication result was ATTEMPTED for /visualcode/rest/getbropr` – ps0604 Sep 05 '20 at 12:36
  • Note that I don't have any type of security set up – ps0604 Sep 05 '20 at 12:38
  • Hi, Servlet spec has authentication support, so these messages are expected for me. Have you check your build process? I suggest you to check that the generated .war file in your target folder does not contain more than one version of the same module. Sometimes when switching branches if the target folder is not properly cleaned you can end up with a faulty artifact. – Ariel Carrera Sep 08 '20 at 22:54