Uploaded image for project: 'Commons Exec'
  1. Commons Exec
  2. EXEC-57

DefaultExecutor.execute() does not return even if child process terminated

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.1
    • None
    • None
    • > uname -smr
      HP-UX B.11.23 ia64

      $ uname -smr
      Linux 2.6.18-194.3.1.el5xen x86_64

    Description

      When script that starts background process is synchronously executed via DefaultExecutor.execute() then method never returns (until child process spawned by child process terminates).

      Here is example if such script:

      echo "Going to start daemon process"
      sleep 1
      cd ./target
      nohup sleep 10 &
      sleep 1
      echo "Daemon process was started"

      Stream handler is used to grab and print output of script. As can be seen from stack trace problem lies in pump threads that call InputStream.read() that does not return when script that we invoke terminates. Instead it returns only once process started by script terminates.

      "Thread-3" daemon prio=10 tid=00c73a00 nid=17 lwp_id=2640638 runnable [2e180000]
      java.lang.Thread.State: RUNNABLE
      at java.io.FileInputStream.readBytes(Native Method)
      at java.io.FileInputStream.read(FileInputStream.java:177)
      at java.lang.UNIXProcess$DeferredCloseInputStream.read(UNIXProcess.java:313)
      at org.apache.commons.exec.StreamPumper.run(StreamPumper.java:105)
      at java.lang.Thread.run(Thread.java:662)

      Locked ownable synchronizers:

      • None

      "Thread-2" daemon prio=10 tid=005fd000 nid=16 lwp_id=2640637 runnable [2e240000]
      java.lang.Thread.State: RUNNABLE
      at java.io.FileInputStream.readBytes(Native Method)
      at java.io.FileInputStream.read(FileInputStream.java:199)
      at java.lang.UNIXProcess$DeferredCloseInputStream.read(UNIXProcess.java:322)
      at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
      at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
      at java.io.BufferedInputStream.read(BufferedInputStream.java:317)

      • locked <628b1970> (a java.io.BufferedInputStream)
        at java.io.FilterInputStream.read(FilterInputStream.java:90)
        at org.apache.commons.exec.StreamPumper.run(StreamPumper.java:105)
        at java.lang.Thread.run(Thread.java:662)

      Locked ownable synchronizers:

      • None

      "main" prio=10 tid=0046aa00 nid=1 lwp_id=-1 in Object.wait() [7fff8000]
      java.lang.Thread.State: WAITING (on object monitor)
      at java.lang.Object.wait(Native Method)

      • waiting on <627e4968> (a java.lang.Thread)
        at java.lang.Thread.join(Thread.java:1186)
      • locked <627e4968> (a java.lang.Thread)
        at java.lang.Thread.join(Thread.java:1239)
        at org.apache.commons.exec.PumpStreamHandler.stop(PumpStreamHandler.java:171)
        at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:363)
        at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:160)
        at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:147)

      I added timeout to join() and call interrupt() but that doesnt help to kill pump threads. Fortunately, these are daemon threads that do not block JVM from exiting. Except from extra daemon threads this solved problem on linux. But that wasnt able to prevent all hangs on HP-UX. Check following stack

      "main" prio=10 tid=00465600 nid=1 lwp_id=-1 runnable [7fffd000]
      java.lang.Thread.State: RUNNABLE
      at java.io.FileInputStream.close0(Native Method)
      at java.io.FileInputStream.close(FileInputStream.java:259)
      at java.lang.UNIXProcess$DeferredCloseInputStream.close(UNIXProcess.java:298)
      at java.io.BufferedInputStream.close(BufferedInputStream.java:451)
      at org.apache.commons.exec.DefaultExecutor.closeStreams(DefaultExecutor.java:281)
      at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:364)
      at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:160)
      at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:147)
      at org.apache.commons.exec.DefaultExecutorTest.testSyncInvocationOfBackgroundProcess(DefaultExecutorTest.java:812)

      I dont have idea how this can be interrupted or timed out except that skip closing streams. But in this case we'll probably leak resources.

      Attachments

        1. EXEC-57.test.patch
          5 kB
          Nikolay Martynov

        Issue Links

          Activity

            People

              sgoeschl Siegfried Goeschl
              nickolay_martinov Nikolay Martynov
              Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: