Standard Output of Child Process using JavaExec

I’m using JavaExec to start a standalone Java application as such:

task standalone(dependsOn: 'classes', type: JavaExec, description: 'Start Standalone server node locally.') {
    main = 'Standalone'
    debug = false
    classpath sourceSets.main.runtimeClasspath
    classpath 'src/local/resources'

The application is configured to use SLF4J for logging and the logback.xml in ‘src/local/resources’ writes all logging to standard out. This works great with all logging messages shown until I hit Ctrl-C in the shell. Gradle does in fact shutdown the standalone application gracefully (I have confirmed that my shutdown hook in the application is executing), but any logging during that shutdown either to SLF4J or just simply System.out.println is no longer shown in the Gradle shell as it is completing the task and exiting. Any idea why all standard output of the child process is being lost?

Are you saying that your shutdown hook cannot log anything? I’m not sure if there are any guarantees about what gets logged during shutdown.

Gradle is not gracefully handling signals effectively, so there’s no guarantee that your launched process exits cleanly before Gradle shuts down.

Actually my application is gracefully shutdown every time (which sounds like a fortunate coincidence since Gradle does no explicit signal handling). When I first noticed the lack of logging to standard out during shutdown, I thought maybe that my application was being abruptly killed (something along the line of ‘kill -9’). To understand what was happening, I inserted a step at the end of my application’s shutdown hook that created a file containing the current PID. On all subsequent shutdowns (graceful or via Ctrl-C), the file was successfully created.

I then thought that maybe the logging system wasn’t flushing the log messages so I switched my logback.xml to instead log to a file vs standard out. On all subsequent shutdowns (graceful and via Ctrl-C), all expected messages from the shutdown hook appeared in the log file.

All this points me to believe that the standard out from the child process of JavaExec is being dropped/discarded before it has been completely read.