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.

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

报告相同问题?

悬赏问题

  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路