5

I'm trying to debug a problem in my Java application that throws no errors, no exceptions and doesn't even crash the app (it seems the failure happens in a separate thread).

The problem seems to be inside a call to a library function (it's JAXBContext.newInstance(String) if that matters). The program will reach the line just before the call, but not the one just after it. My catch blocks are not entered and the program just continues to run.

The problem happens while trying to render an XML response to a web request that came in via Struts. The request has been handled and the code should marshal the response object. The client gets a response right away (so the code doesn't seem to hang in a loop), but it's just empty.

I have set a breakpoint just before the problematic line but the debugger just runs over it, I haven't a clue why.

I'm using eclipse and the application runs inside an OSGi container (Apache Felix) that was started with -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y. From within Eclipse I then use the Debug settings for "Remote Java application" to connect the debugger.

What are techniques to get at such a problem?

Hanno Fietz
  • 30,799
  • 47
  • 148
  • 234
  • 2
    Are you sure the IDE is pointing at the same source code that formed the binaries on the server? – Nick Holt Jun 24 '09 at 09:43
  • Yes, it's all on my local machine and the OSGi container is running the code directly from the output directory of my IDE. – Hanno Fietz Jun 24 '09 at 09:50
  • I'm not familiar with the OSGi container, does it, like JBoss, move the deployed binaries to another directory? I'd try making a change to your code, a System.out.println or something similar, then make sure it gets executed to confirm this. I've normally found the debugger skipping lines of code indicates the IDE and server are out of sync with one another. – Nick Holt Jun 24 '09 at 09:57
  • Yup, that sounds plausible, but I have no idea how they should be able to get out of sync. There's only one copy of the source code and the binaries that are run are those that the IDE produces. – Hanno Fietz Jun 24 '09 at 10:11
  • If this is the problem then binaries you think are being run aren't the ones actually being run. It's common for the server to unpack the archive file to another directory. With JBoss this is pretty reliable but in a development environment where you're deploying continuously I've seen the hot-deploy stop working - JBoss stops unpacking new archive files and the server continues to run on the old binaries. I'd imagine you could have a similar problem here. On JBoss you solve it by removing the archive file, bouncing the server then redeploying. Not sure with OSGI, but I'd try that. – Nick Holt Jun 24 '09 at 10:29

4 Answers4

6

Probably an obvious question, but are you sure you are catching Throwable? An unchecked exception could easily cause the thread in question to die (assuming no one above you in the call stack is catching it either.)

Since you are suspending the VM on startup with your debug arguments, I assume you have confirmed that the debugger is attaching correctly. The fact that you say the debugger skips right past the call is very suspect. Are you able to hit any breakpoints in this application? What about in this Class? What about in this thread?

How did you narrow down the line in question without the debugger? println/debugging to a file?

Can you paste a code snippet of the method in question?

You could confirm the theory that the thread is dying by creating a second thread before the problem occurs and joining it to the thread you think is dying. Then the second thread's run() method would be invoked when the thread in question exits, and you'd know it died (but would still not know why.)

In answer to your general question, when I have a bug in a Java app that I can't reproduce in the debugger (which happens from time to time for various reasons), I incrementally modify my code with sysout printlns or output to files. If necessary, I may also modify the code my code is invoking. If you don't have the source code to the code you are invoking, you can try one of the many BCI frameworks to inject your byte code into the methods in question. It's a tedious process, but only happens occasionally.

jptsetme
  • 158
  • 6
2

You could try getting a Thread Dump - that will tell you if any methods are blocking (e.g. waiting for input). [Edit: re-reading your original question, getting a thread dump probably won't help as it looks like nothing is actually blocking. But I'm leaving it here as I find it useful in many other situations!]

If you think the error is happening in another thread you could also set an UncaughtExceptionHandler to try and catch it.

  • Blocking: no, not this time. UncaughtExceptionHandler was a nice idea, unfortunately, it didn't catch anything either. – Hanno Fietz Jun 24 '09 at 10:08
1

If you're sure the problem is somewhere within that method, you could try looking at the JAXB source code.

EDIT:

Well, if it gets really bad you can build your own private copy with debugging instrumentation. I hope you won't have to resort to that.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
0

perhaps inside the call there is an infitite loop happening and this is why you get no further - but this might not cause a crash (unless memory is being used in each loop).

Grouchal
  • 9,756
  • 6
  • 34
  • 46
  • 1
    No, I don't think so. The error happens upon handling a web request coming in via Struts and the client gets a result (which is empty) right away. So the app doesn't hang, it jumps out of the processing. – Hanno Fietz Jun 24 '09 at 09:46