24

My application has started to non-deterministically fail after upgrading to Java 8. It doesn't throw an exception or print an error message. The only sign of its failure is the exit code -559038737. Has anyone encountered this?

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
  • 15
    If you read the hex message, it says "dead beef". This is a common trick used by memory profilers to indicate invalid memory. – Sergey Kalinichenko Apr 29 '14 at 16:41
  • @dasblinkenlight This an *exit code*, nothing to do with the contents of RAM. There must be a better explanation. – Marko Topolnik Apr 29 '14 at 18:43
  • 3
    OP, your application may actually be calling `System.exit(0xDEADBEEF)` somewhere inside 3rd party code. – Marko Topolnik Apr 29 '14 at 18:46
  • 2
    @MarkoTopolnik I will kill the library author who used System.exit if I ever find him. I suppose I can try setting a breakpoint on that function. It does seem strange to use that magic number in Java source code rather than in C. – Aleksandr Dubinsky Apr 30 '14 at 04:00
  • 2
    If my guess is right, you are using a Java library written by a C enthusiast. Sprinkling a bit of C magic over Java must have felt good :) – Marko Topolnik Apr 30 '14 at 07:33
  • I haven't found any notions of `0xDEADBEEF` as an exit code in either JDK or HotSpot sources. This might be a library. Place a breakpoint on `java.lang.Runtime.exit` and on `java.lang.Runtime.halt` if possible. If it isn't possible to place a breakpoint on the production system, you may want to recomple `Runtime.java` class to print the stack trace on `exit` and `halt`. – apangin Apr 30 '14 at 12:37
  • @apangin What do you mean to recompile tgose classes? Is there a way I can include them in my source code and have them picked up instead of the official ones? – Aleksandr Dubinsky Apr 30 '14 at 13:25
  • Yes, you can. Extract `java/lang/Runtime.java` from `src.zip` included in JDK, modify it as you wish, compile with javac, and finally include in the bootstrap classpath when running your application using `-Xbootclasspath/p:/path/to/alt/classes` command line option. – apangin Apr 30 '14 at 15:02
  • 5
    For the record, OXCAFEBABE seems to be more popular in JVM environments. – Totoro Apr 30 '14 at 21:37
  • @apangin if I simply include it at `src/main/java/java/lang/Runtime.java` in my Maven project and build the jar, what JVM flag should I use? – Aleksandr Dubinsky Apr 30 '14 at 21:51
  • @AleksandrDubinsky `-Xbootclasspath/p:/path/to/project.jar` – apangin May 01 '14 at 00:23
  • What libraries are you using? – Anubian Noob May 02 '14 at 15:04
  • 2
    @Totoro The first 4 bytes of every valid Java .class file is 0xCAFEBABE. – Jeff Scott Brown May 06 '14 at 02:40
  • Use SecurityManager and handle system exit - the rest leave untouched, it's few lines of code and can be used in production environment. – bestsss May 06 '14 at 17:05
  • Something similar.. http://stackoverflow.com/questions/5907614/0xdeadbeef-vs-null – Syam S May 07 '14 at 18:54
  • @AleksandrDubinsky debug you application and post the snippet where `dead beef` occurs. – Vishrant May 08 '14 at 08:54
  • Yep, "DEADBEEF" is commonly used to initialize heap, etc, to detect invalid references (due to "dangling pointers", etc). I would not expect a skilled programmer to intentionally use that value as a `exit` return code, so either the exit is due to an unskilled programmer or there has indeed been some sort of "wild" reference. – Hot Licks May 08 '14 at 16:30
  • @Totoro - It would be a rather inexperienced programmer who initialize storage to "CAFEBABE", as that would lead to confusion as to whether the value had somehow been copied from a .class file header. – Hot Licks May 08 '14 at 16:31

1 Answers1

4

That exit code probably comes from Apache Commons Exec:

public interface Executor {

/** Invalid exit code. */
int INVALID_EXITVALUE = 0xdeadbeef;
...

There are some changes in Java 8 that might have introduced a bug.

But without knowing your classpath and code, this is just an educated guess.

Maybe you are using the asynchronous way to use Commons Exec:

DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();

Executor executor = new DefaultExecutor();
executor.execute(cmdLine, resultHandler);

int exitValue = resultHandler.waitFor();

return exitValue;

So the exception is only captured in the resultHandler, but not print on stderr automatically?

DiegoG
  • 814
  • 8
  • 17
  • I use Commons Exec to launch a JVM process. Do you think a JVM crash would cause Exec to return this exit code but not capture the error output that the JVM prints out? I have seen a similar issue in Java 8 where the stderr output is not recorded when the called java app uses System.Exit(). Output of a stack trace of an unhandled exception, though, seems to get recorded. – Aleksandr Dubinsky May 08 '14 at 18:17
  • I edited the answer to address that question, maybe you are using the non-blocking way to use that library, which doesn't print the stacktrace automatically. – DiegoG May 09 '14 at 01:07
  • Not seeing (some) `stderr` output (or `stdout` for that matter) wouldn't be at all surprising on `System.exit()` since the output buffers won't get flushed, or might not on some JVMs. – Lawrence Dol May 09 '14 at 01:15