skip to Main Content

I am implementing a JAR runner script in a Docker container.
I pick up all the JAR files in a specific directory (in a Docker volume) and run all of them after each other as a background process.
If the JAR file does not start properly, then I need to show an error on the console and log the exit code.

This is the code of the runner bash script (run-jars.sh):

number_of_jars=$(find "$JAR_HOME" -maxdepth 1 -type f -name "*.jar" | wc -l)
printf "%s | [DEBUG] JAR files in the %s directory: %sn" "$(date +"%Y-%b-%d %H:%M:%S")" "$JAR_HOME" "$number_of_jars"

for jar_file in "$JAR_HOME"/*.jar; do
   printf "%s | [INFO]  starting %s at the background...n" "$(date +"%Y-%b-%d %H:%M:%S")" "$jar_file"
   nohup java -jar "$jar_file" 2>&1 &

   exit_code=$?
   pid=$!
   printf "%s | [DEBUG] PID       of the %s is %sn" "$(date +"%Y-%b-%d %H:%M:%S")" "$jar_file" "$pid"
   printf "%s | [DEBUG] Exit code of the %s is %sn" "$(date +"%Y-%b-%d %H:%M:%S")" "$jar_file" "$exit_code"

   timeout 5 tail --pid=$pid -f /dev/null
   exit_code=$?
   printf "%s | [DEBUG] Exit code of the %s is %sn" "$(date +"%Y-%b-%d %H:%M:%S")" "$jar_file" "$exit_code"
   if [ "$exit_code" -ne 0 ]; then
      printf "%s | [ERROR] Java application %s exited with an error: %s" "$(date +"%Y-%b-%d %H:%M:%S")" "$jar_file" "$exit_code"
   fi
done

The loop works fine and JARs has been started but my exit-code checker does not work. The exit code I get is allways ZERO despite one JAR is corrupt deliberately.

Log:

2024-Mar-03 13:38:24 | [DEBUG] JAR files in the /jars-to-run directory: 2
2024-Mar-03 13:38:24 | [INFO]  running /jars-to-run/aa.jar at the background...
Error: Invalid or corrupt jarfile /jars-to-run/aa.jar
2024-Mar-03 13:38:24 | [DEBUG] PID       of the /jars-to-run/aa.jar is 139
2024-Mar-03 13:38:24 | [DEBUG] Exit code of the /jars-to-run/aa.jar is 0
2024-Mar-03 13:38:24 | [DEBUG] Exit code of the /jars-to-run/aa.jar is 0
2024-Mar-03 13:38:24 | [INFO]  running /jars-to-run/rest-template-0.0.2.jar at the background...
2024-Mar-03 13:38:24 | [DEBUG] PID       of the /jars-to-run/rest-template-0.0.2.jar is 146
2024-Mar-03 13:38:24 | [DEBUG] Exit code of the /jars-to-run/rest-template-0.0.2.jar is 0

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to the doc shared by @pjh I was able to write a proper code that checks the Java processes properly.

    bash script:

    number_of_jars=$(find "$JAR_HOME" -maxdepth 1 -type f -name "*.jar" | wc -l)
    printf "%s | [DEBUG] JAR files in the %s directory: %sn" "$(date +"%Y-%b-%d %H:%M:%S")" "$JAR_HOME" "$number_of_jars"
    
    for jar_file in "$JAR_HOME"/*.jar; do
      printf "%s | [INFO]  starting %s at the background...n" "$(date +"%Y-%b-%d %H:%M:%S")" "$jar_file"
      java -jar "$jar_file" 2>&1 &
      pid=$!
      timeout 5 bash -c 'while true; do if kill -0 '"$pid"' 2>/dev/null; then echo '"$(date +"%Y-%b-%d %H:%M:%S") | [DEBUG] $jar_file started successfully"'; break; fi; sleep 0.5; done' || printf "%s | [ERROR] an unexpected error has occurred while starting %sn" "$(date +"%Y-%b-%d %H:%M:%S")" "$jar_file"
    done
    

    Log:

    2024-Mar-04 13:44:47 | [DEBUG] JAR files in the /jars-to-run directory: 2
    2024-Mar-04 13:44:47 | [INFO]  starting /jars-to-run/aa.jar at the background...
    Error: Invalid or corrupt jarfile /jars-to-run/aa.jar
    2024-Mar-04 13:44:52 | [ERROR] an unexpected error has occurred while starting /jars-to-run/aa.jar
    2024-Mar-04 13:44:52 | [INFO]  starting /jars-to-run/rest-template-0.0.2.jar at the background...
    2024-Mar-04 13:44:52 | [DEBUG] /jars-to-run/rest-template-0.0.2.jar started successfully
    

    I also would like to mention that we changed the way we check the state of the Java process. We will "ping" here the healthcheck service implemented in the application (spring-boot actuator, hashicorp consul healthcheck, etc.) which provides better state info about the app than just checking the Unix process state. So that we do not use this Unix process check bash code anymore.


  2. You cannot collect the exit status of a background process immediately after launching it.

    Try this :

    declare -A pids
    for jar_file in "$JAR_HOME"/*.jar; do
        nohup java -jar "$jar_file" 2>&1 &
        pids[$!]="$jar_file"
    done
    while test -n "${pids[*]}" && { wait -n -p pid; status=$?; }; do
        echo "java process with jar:[${pids[$pid]}] and pid:$pid exited with status:$status"
        unset "pids[$pid]"
    done
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search