The obvious solution in this case is to not involve the shell:
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
'selenium-server.jar',
"-port",
str(selenium_port)]
log = open(log_file_path, 'a')
selenium_server_process = subprocess.Popen(command,
cwd=selenium_folder_path,
stdout=log,
stderr=subprocess.STDOUT,
env=env)
This will make the process be the Java process directly. Keep in mind that it may still spawn processes that are not part of the process group, so os.killpg may still not know about killing them.
If you have a reason to invoke the shell (the above code does not, and there are few things you cannot do without the shell, but suppose you do), you would have to make the shell pass you the pid of the process it started somehow. Doing this is not straightforward, and rather situational.