Deadlock issue when using Python’s subprocess module
I ran into an issue yesterday when calling an external Java application from Python using the subprocess module. The Java application loaded but appeared to have stopped executing after loading its properties files (last entry in the log file is after loading the properties file).
My Python code looked something like this:
import subprocess javaApplication = subprocess.Popen(["java", "-jar", "application.jar"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # The wait() function is actually not a good idea to use # when using stdout=PIPE or stderr=PIPE. Use the communicate() # function instead, so this line is actually not needed. javaApplication.wait() (stdout, stderr) = javaApplication.communicate()<br>
If I don’t use the stdout=subprocess.PIPE and stderr=subprocess.PIPE the Java application executes properly, but I need to capture the standard output and standard error from the Java application. Another thing I noticed is if I disable the console appender in log4j (logging service for Java), the Java applications executes normally as well. So there appears to be some conflict between the Java and the Python processes.
Since I don’t really need log4j to output to the console this would’ve solved my problem but it was still bothering me so I played with it a little bit more. I enabled the console appender in log4j again but this time I commented out javaApplication.wait(). After doing that the Java app executed normally. I thought I needed javaApplication.wait() to capture the standard out/error but it turned out it wasn’t necessary as thecommunicate() function took care of it.
I looked back at the subprocess module’s documentation and there was actually a mention there that the wait()function can cause a deadlock when using stdout=PIPE or stderr=PIPE. I guess I should really pay more attention to a module’s documentation a bit more next time before using that module :).