Why can’t Python execute java.exe via subprocess?

After upgrading Java from 1.6 to 1.7 x64 (on Windows 7), I suddenly can’t launch java.exe via Python 2.7’s subprocess module anymore. The following script used to just work:

import subprocess

Now it fails like this:

Traceback (most recent call last):
  File ".\tst.py", line 2, in <module>
  File "C:\Python27\lib\subprocess.py", line 506, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:\Python27\lib\subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "C:\Python27\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
WindowsError: [Error 2] The system cannot find the file specified

I have also confirmed that C:\Windows\system32\java.exe does indeed exist, is an application, and can be executed from the command shell.

What goes wrong here?

I’ve found that I can start C:\Program Files\Java\jre7\bin\java.exe from Python, so C:\Windows\system32\java.exe must be some weird pseudo-shortcut although technically a Windows application. Version 1.7 must’ve messed it up somehow, since I just confirmed Version 1.6 is fine.

Best answer

Assuming that there is a java.exe at “C:\Windows\System32” is not a particularly safe assumption. Even the assumption there is a “C:\Windows\System32” on the system isn’t safe: Windows could reside on any fixed drive on the computer.

But even if there is a “C:\Windows\System32\java.exe”, this might not be visible for 32-bit processes under Win64. Windows does some interesting things here in the name of backwards compatibility, you might want to look at http://en.wikipedia.org/wiki/WoW64.

Finding the Java version you’re looking for – and there can be many – can be a thankless task. If you don’t particularly care about which Java you find, try the JAVA_HOME environment variable. It’s not always there, but if it is, you’re done and it’s probably the most portable way of finding a JVM. If it’s not there, you can’t go wrong by setting it, and many Java applications can make use of that variable.

Then again, Java just might be on the PATH, in which case removing the everything but ‘java’ in the subprocess call will do the trick. It can’t hurt to try.