2016: same question; I've been clicking through related questions for a few minutes, but still couldn't find any solution that is generally agreed upon. Here is a Scala version inspired by LRBH10's Java code in the answer linked by wingedsubmariner:
import scala.sys.process.Process
def pid(p: Process): Long = {
val procField = p.getClass.getDeclaredField("p")
procField.synchronized {
procField.setAccessible(true)
val proc = procField.get(p)
try {
proc match {
case unixProc
if unixProc.getClass.getName == "java.lang.UNIXProcess" => {
val pidField = unixProc.getClass.getDeclaredField("pid")
pidField.synchronized {
pidField.setAccessible(true)
try {
pidField.getLong(unixProc)
} finally {
pidField.setAccessible(false)
}
}
}
case _ => throw new RuntimeException(
"Cannot get PID of a " + proc.getClass.getName)
}
} finally {
procField.setAccessible(false)
}
}
}
val proc = Process("echo 'blah blah blaaah'").run()
println(pid(proc))
WARNING: scala code runner is essentially just a bash script, so when you use it to launch scala programs, it will do thousand things before actually starting the java
process. Therefore, the PID of the java
-process that you are actually interested in will be much larger than what the above code snippet returns. So this method is essentially useless if you start your processes with scala
. Use java
directly, and explicitly add Scala library to the classpath.