Reputation:
I have JVM and all dependencies for my Java program ready. With Java I would run like:
javac HelloWorld.java
java HelloWorld
Now I want to, in Linux environment, control this Java program processes using Go's cmd package. In Go, when you run command you are given the PID. With this PID, I want to terminate the Java program whenever j want and restart using the same cmd package. Would this work correctly as long as I have JVM installed? I want to do:
cmd := exec.Command("bash", "-c", " "java HelloWorld")
cmd.Start()
syscall.Kill(cmd.Process.Pid)
Thanks!
Upvotes: 2
Views: 595
Reputation: 503
In short, yes.
As a test, with added interrupt handling so your own Go process doesn't terminate this will work:
package main
import (
"os/exec"
"syscall"
"os"
"os/signal"
"fmt"
)
func main() {
cmd := exec.Command("bash", "-c", "java HelloWorld")
err := cmd.Start()
fmt.Printf("Starting java proccess with pid %d\n", cmd.Process.Pid)
if err != nil {
// do something about it
}
c := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(c, os.Interrupt)
signal.Notify(c, syscall.SIGTERM)
go func() {
<-c
fmt.Printf("Sending interrupt to pid: %d\n", cmd.Process.Pid)
syscall.Kill(cmd.Process.Pid, syscall.SIGHUP)
done <- true
}()
<-done
}
Companion Java class:
public class HelloWorld {
public static void main(String[] args) throws Exception {
System.out.println("Hello World from Go! But you cant see me :)");
while (true) {
System.out.println("you cant see this because I am outing to the STDOUT of a subshell!");
Thread.sleep(5000);
}
}
}
But it is full of gotchas. As long as your Go process exits normally, it will send the signal you specify (sighup would be natural choice, if I'd venture a guess) to the java pid. But you need to ensure that you wont let a zombie in case your own Go process crash or in case your java application hangs on after failing to shut down cleanly when you tell it to. Saving that pid to a /tmp/ file and doing all sorts of things with it in case of a restart could be interesting, but you know your needs.
Edit: controlling a JVM process from another program might get finicky quick. You should evaluate if you really want to do that. If you are in Linux, I'd take a look at the SysV init/systemd/upstart/start-stop-daemon system your distro uses if your companion java program acts as a daemon.
Upvotes: 1