0

I'm running a JAX-RS web service on EE6 (EAP 6.4, if that plays a role).

I'd like to be able to tell if the response was delivered to the client, but I can't seem to be able to pick up on errors.

I wrote a sandbox example:

@POST
@Path("/delay")
@Produces(MediaType.APPLICATION_XML)
public String justWait(InputStream is) throws IOException, InterruptedException {
    String theString = IOUtils.toString(is, "UTF-8");
    log.info("Received body: " + theString);
    log.info("Now waiting a bit");
    Thread.sleep(5000);
    log.info("Back, sending respoonse.");
    return "<OK/>";
}

But whatever I do, whenever I send a POST, the log output is pretty and clean. Hit "abort" in the REST plugin? Nothing. Close the browser? Silence. Use curl and Ctrl-C it halfways? Nøpe.

I'm logging all incoming request using a javax.servlet.annotation.WebFilter, and I can also see the outgoing response, but it's of course after this logging that the delivery would fail.

How can I tell that my response wasn't sent?

If there are solutions in EE7, I'd also like to hear about them. We'll upgrade soon anyway.

Antares42
  • 1,406
  • 1
  • 15
  • 45
  • why not just run your jboss with the debug-socket opened, remote-debug it from your IDE and set a breakpoint? also, just try out something more proper when shooting on your API, why not chrome's advanced-rest-client plugin or postman - your logging setup might be faulty but just debug it and you'll know? – Ola Aronsson Dec 08 '17 at 23:55
  • Maybe I wasn't clear enough, but you're looking at this from the wrong side. I don't want to debug something, I want to know when my customers didn't wait for a response. What happened was that several times in the last months, one (fairly incompetent) customer using our API claims we didn't deliver a response. All my logs are telling me is that they sent a request and we processed it. But whether the HTTP response was ever delivered, I can't prove to them. – Antares42 Dec 12 '17 at 09:10
  • Can you use your server's access logs as proof? – Dele Taylor Dec 12 '17 at 10:54
  • But that is exactly the problem: My server log does not show whether an HTTP response was *succsessfully delivered* to the client. I know that I have generated the response correctly, and sent it - but I would have expected a ``ClientAbortException`` or a ``SocketException`` or something of that kind in those cases when the client hangs up and no longer listens to the response. – Antares42 Dec 14 '17 at 07:35
  • in the majority of cases, nothing will be thrown server side; they say your server does not respond yet everything indicates it does and there is no error indication whatsoever on your side - it's more a question of digging into _how_ their client does not get the response? – Ola Aronsson Dec 14 '17 at 22:58

2 Answers2

0

Try using a servlet filter to trap exceptions when the socket is closed prematurely. Make sure it's first in your web.xml.

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class StackHunterServletFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        try {
            try {
                chain.doFilter(request, response2);
            } catch (Throwable e) {
                e.printStackTrace();
                throw e;
            }
        } catch (IOException e) {
            throw e;
        } catch (ServletException e) {
            throw e;
        } catch (RuntimeException e) {
            throw e;
        } catch (Error e) {
            throw e;
        } catch (Throwable e) {
            throw new ServletException(e.getMessage(), e);
        }
    }

}
Dele Taylor
  • 300
  • 5
  • 11
  • I already had a filter in place, but it never caught any exceptions. Good idea putting it first in the ``web.xml``, but unfortunately it doesn't make a difference. It looks like it's not until all the filters are through, that the response is actually being sent, and obviously I can't catch the error before it happens. – Antares42 Dec 12 '17 at 09:27
  • I tried again with a ``WebListener`` which [sits between the Servlet layer and the client](https://docs.oracle.com/cd/B14099_19/web.1012/b14017/filters.htm#i1000029), but even that just tells me that the request started and ended, and does not notice if (after it its run) the sending of the response failed. – Antares42 Dec 14 '17 at 12:19
0

hmm, sorry, I see. You can use a filter as you're already using, maybe even add a separate ResponseFilter capturing all actual responses (see for instance Logging request and response in one place with JAX-RS) sent from your side which could be said to prove exactly that. Proving they actually recieve your responses is quite different; if the customer is accessing your API programmatically, there is no other way then getting grips on their transport logging, or, make a customer visit and help them set it up : you do have the common interest of solving this, right? It they just browse your API then.. I dunno, the former is your only option?

  • just some more comments, following your comment:

yep, as I said, the filter, even if working, will not say anything regarding the actual delivery of your responses. for example, I'm currently sometimes thrown into this thing now and then where we have über restricted point-to-point access over VPN with SSL-verification both ways, heavy firewalling on both sides and then, on the way in, there are a number of proxies between us and our destination. in most cases, we act as clients and it has happened many times that our fw has had some kind of problem or some of our proxies have been misconfigured or down or the SSL-certs are out of date or just.. network issues on our side. in these cases the remote server has no way of telling anything went wrong, they just respond - it is you, the client, who has the problems and it is on your side errors will popup whenever you cannot read responses. so.. there is not really any point avoiding the obvious here I guess, first thing you do is ask them well, "how did you notice there was no response"? timeouts/socket closed? different type of errors usually indicate the domain from where it arose. then you just follow the trace and you will find the point of termination. however, in your case it seems to happen.. "sometimes" rather then your network toggling "off" - then I would, if the error logs they sent me didn't tell me exactly what was going on, ask the customer what their client is actually doing. would it be possible that they connect single-thread and another request is issued before the current response is read? stranger things (and more horrid code) has been seen to execute, right? I think I'm just saying that you should focus not on your API, it probably works, focus on the actual client which, in contrast to your server, should do two things instead of just one.

Ola Aronsson
  • 411
  • 4
  • 7
  • Unfortunately, the logging setup described in your linked article uses the EE7 framework, and we're currently stuck with EE6. We'll be able to overcome that, but still - I'm uncertain that said logging would catch IO errors arising *after* JAX-RS is done and the framework tries to send stuff back to the client. – Antares42 Dec 14 '17 at 07:49
  • just added some more comments in the answer as these comment fields are , apparently, really short. – Ola Aronsson Dec 14 '17 at 22:02
  • Thanks for your input. Yes, it seems the most promising way forward is to talk to the customer and look at what their client does. – Antares42 Dec 17 '17 at 14:50