Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get process id of Scala.sys.process.Process

Tags:

scala

If I started a process using Scala Process/ProcessBuilder. How can I get the pid of the process that was created?

I could not find any mention of the pid in the official docs: http://www.scala-lang.org/api/2.10.4/index.html#scala.sys.process.Process http://www.scala-lang.org/api/2.10.4/index.html#scala.sys.process.ProcessBuilder http://www.scala-lang.org/api/2.10.4/index.html#scala.sys.process.package

like image 274
mbdev Avatar asked Apr 24 '14 21:04

mbdev


1 Answers

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)
            }
          }
        }
        // If someone wants to add support for Windows processes,
        // this would be the right place to do it:
        case _ => throw new RuntimeException(
          "Cannot get PID of a " + proc.getClass.getName)
      }
    } finally {
      procField.setAccessible(false)
    }
  }
}

// little demo
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.

like image 125
Andrey Tyukin Avatar answered Nov 03 '22 00:11

Andrey Tyukin