donglu3087 2016-03-10 01:53
浏览 36
已采纳

使用Go管理Java流程

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!

  • 写回答

1条回答 默认 最新

  • dtu36380 2016-03-10 02:59
    关注

    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
    ", 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
    ", 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题