英文:
How to start a process?
问题
package main
import "fmt"
import "os"
import "log"
func main() {
var name string
name="\jrex64\bin\java.exe"
var path="-Xbootclasspath:jrex64\lib\rt.jar;"+
"jrex64\lib\jfxrt.jar;"+
"jrex64\lib\resources.jar;"+
"jrex64\lib\ext\sunjce_provider.jar;"+
"jrex64\lib\ext\zipfs.jar;"+
"jrex64\lib\ext\sunmscapi.jar;"+
"jrex64\lib\ext\sunec.jar;"+
"jrex64\lib\ext\dnsns.jar;"+
"jrex64\lib\ext\access-bridge-64.jar;"+
"jrex64\lib\security\local_policy.jar;"+
"jrex64\lib\jce.jar;"+
"jrex64\lib\jfr.jar;"+
"jrex64\lib\jsse.jar;"+
"jrex64\lib\charsets.jar;"+
"jrex64\lib\";
var args[] string=make([]string,4)
args[0]="-verbose"
args[1]=path;
args[2]="-cp Ganesha_lib\*"
args[3]="-jar Ganesha.jar"
var attr* os.ProcAttr
proc,err:=os.StartProcess(name,args,attr)
proc.Wait();
if err!=nil {
fmt.Println("an error occurred.\n")
log.Fatal(err)
}
}
英文:
I try to start a JVM out of a Google Go program that looks like this:
package main
import "fmt"
import "os"
import "log"
func main() {
var name string
name="\\jrex64\\bin\\java.exe"
var path="-Xbootclasspath:jrex64\\lib\\rt.jar;"+
"jrex64\\lib\\jfxrt.jar;"+
"jrex64\\lib\\resources.jar;"+
"jrex64\\lib\\ext\\sunjce_provider.jar;"+
"jrex64\\lib\\ext\\zipfs.jar;"+
"jrex64\\lib\\ext\\sunmscapi.jar;"+
"jrex64\\lib\\ext\\sunec.jar;"+
"jrex64\\lib\\ext\\dnsns.jar;"+
"jrex64\\lib\\ext\\access-bridge-64.jar;"+
"jrex64\\lib\\security\\local_policy.jar;"+
"jrex64\\lib\\jce.jar;"+
"jrex64\\lib\\jfr.jar;"+
"jrex64\\lib\\jsse.jar;"+
"jrex64\\lib\\charsets.jar;"+
"jrex64\\lib\\";
var args[] string=make([]string,4)
args[0]="-verbose"
args[1]=path;
args[2]="-cp Ganesha_lib\\*"
args[3]="-jar Ganesha.jar"
var attr* os.ProcAttr
proc,err:=os.StartProcess(name,args,attr)
proc.Wait();
if err!=nil {
fmt.Println("an error occurred.\n")
log.Fatal(err)
}
}
It's my first Go program. And i'm totally overwhelmed by getting the following error:
> panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x4278b5]
goroutine 1 [running]:
os.startProcess(0x4aacb4, 0x14, 0xf840001eb0, 0x500000005, 0x0, ...)
C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist767862039/go/src/pkg/os/exec_posix.go:28 +0x152
os.StartProcess(0x4aacb4, 0x14, 0xf840001eb0, 0x500000005, 0x0, ...)
C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist767862039/go/src/pkg/os/doc.go:24 +0x5c
main.main()
D:/MyGoProject/src/main.go:60 +0x23c
goroutine 2 [syscall]:
created by runtime.main
C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist767862039/go/src/pkg/runtime/proc.c:221
Process finished with exit code 2
How do i have to interpret this error code? What went wrong? And how can i get the JVM startet - it's situated in a subdirectory of the Go executable file.
答案1
得分: 20
通常建议不直接使用os.StartProcess。相反,使用具有更简单接口的os/exec。以下是我如何启动一个java子进程并等待其完成的示例代码。
package main
import (
"fmt"
"log"
"os/exec"
"strings"
)
func main() {
var java = "\\jrex64\\bin\\java.exe"
var path = []string{
"jrex64\\lib\\rt.jar",
"jrex64\\lib\\jfxrt.jar",
"jrex64\\lib\\resources.jar",
"jrex64\\lib\\ext\\sunjce_provider.jar",
"jrex64\\lib\\ext\\zipfs.jar",
"jrex64\\lib\\ext\\sunmscapi.jar",
"jrex64\\lib\\ext\\sunec.jar",
"jrex64\\lib\\ext\\dnsns.jar",
"jrex64\\lib\\ext\\access-bridge-64.jar",
"jrex64\\lib\\security\\local_policy.jar",
"jrex64\\lib\\jce.jar",
"jrex64\\lib\\jfr.jar",
"jrex64\\lib\\jsse.jar",
"jrex64\\lib\\charsets.jar",
"jrex64\\lib\\",
}
pathflag := "-Xbootclasspath:" + strings.Join(path, ";")
cmd := exec.Command(java, "-verbose", pathflag, "-cp Ganesha_lib\\*", "-jar Ganesha.jar")
err := cmd.Run()
if err != nil {
fmt.Println("an error occurred.\n")
log.Fatal(err)
}
}
如果你好奇的话,你得到那个panic的原因是attr是一个空指针。相反,你可以使用attr := new(os.ProcAttr)
。
英文:
It is normally recommended you don't use os.StartProcess directly. Instead, use os/exec which has a much easier interface. Here is how I would start a java subprocess and wait for it to complete.
http://play.golang.org/p/APlp9KK9wx
package main
import (
"fmt"
"log"
"os/exec"
"strings"
)
func main() {
var java = "\\jrex64\\bin\\java.exe"
var path = []string{
"jrex64\\lib\\rt.jar",
"jrex64\\lib\\jfxrt.jar",
"jrex64\\lib\\resources.jar",
"jrex64\\lib\\ext\\sunjce_provider.jar",
"jrex64\\lib\\ext\\zipfs.jar",
"jrex64\\lib\\ext\\sunmscapi.jar",
"jrex64\\lib\\ext\\sunec.jar",
"jrex64\\lib\\ext\\dnsns.jar",
"jrex64\\lib\\ext\\access-bridge-64.jar",
"jrex64\\lib\\security\\local_policy.jar",
"jrex64\\lib\\jce.jar",
"jrex64\\lib\\jfr.jar",
"jrex64\\lib\\jsse.jar",
"jrex64\\lib\\charsets.jar",
"jrex64\\lib\\",
}
pathflag := "-Xbootclasspath:" + strings.Join(path, ";")
cmd := exec.Command(java, "-verbose", pathflag, "-cp Ganesha_lib\\*", "-jar Ganesha.jar")
err := cmd.Run()
if err != nil {
fmt.Println("an error occurred.\n")
log.Fatal(err)
}
}
In case you are curious, the reason you got that panic was that attr is a nil pointer. Instead, you could have done attr := new(os.ProcAttr)
.
答案2
得分: 14
以前的答案实际上没有描述如何使用os.StartProcess()。这里有一个例子:
cmdToRun := "/path/to/someCommand"
args := []string{"someCommand", "arg1"}
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr}
if process, err := os.StartProcess(cmdToRun, args, procAttr); err != nil {
fmt.Printf("ERROR Unable to run %s: %s\n", cmdToRun, err.Error())
} else {
fmt.Printf("%s running as pid %d\n", cmdToRun, process.Pid)
}
请注意,必须初始化ProcAttr.Files字段 - 如果不这样做,您可能会在os包中深处得到一个索引越界错误。如果您想要在自己的代码中提供输入或处理新进程的输出,可以使用管道来处理文件。您还可以指定Dir(起始目录)和Env(环境变量)字段。
英文:
The previous answers don't actually describe how to use os.StartProcess(). Here's an example:
cmdToRun := "/path/to/someCommand"
args := []string{"someCommand", "arg1"}
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr}
if process, err := os.StartProcess(cmdToRun, args, procAttr); err != nil {
fmt.Printf("ERROR Unable to run %s: %s\n", cmdToRun, err.Error())
} else {
fmt.Printf("%s running as pid %d\n", cmdToRun, process.Pid)
}
Note that it's necessary to initialize the ProcAttr.Files field - if you don't, you may get an index out of bounds error deep in the os package. You can use pipes for the files if you want to provide input or process output from the new process in your own code. You may also want to specify the Dir (starting directory) and Env (environment variables) fields.
答案3
得分: 3
这里:
var attr* os.ProcAttr
proc, err := os.StartProcess(name, args, attr)
attr
变量是空的,当在 os.StartProcess
中解引用时会导致你看到的错误。
英文:
Here:
var attr* os.ProcAttr
proc, err := os.StartProcess(name, args, attr)
The attr
variable is nil and when dereferenced in os.StartProcess
it causes the error you see.
答案4
得分: 2
在Windows上,os.ProcAttr不能留空。在Dir中必须设置为空字符串,并且在Sys中必须设置为&syscall.SysProcAttr{}。以下代码应该可以工作:
name := "\\jrex64\\bin\\java.exe"
libs := "-Xbootclasspath:jrex64\\lib\\rt.jar;" +
// 添加所有的库
"jrex64\\lib\\";
args := []string{"-verbose", libs, "-cp Ganesha_lib\\*", "-jar Ganesha.jar"}
attr := &os.ProcAttr{
"",
nil,
[]*os.File{os.Stdin, os.Stdout, os.Stderr},
&syscall.SysProcAttr{}} //CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, }
}
proc, err := os.StartProcess(name,args,attr);
if err != nil {
log.Fatalf("start process: %v", err)
}
_, err = proc.Wait();
if err != nil {
log.Fatalf("wait: %v", err)
}
英文:
On Windows, os.ProcAttr cannot be left empty. At Dir must be set to an empty string and Sys must be set to &syscall.SysProcAttr{}. The following should work:
name := "\\jrex64\\bin\\java.exe"
libs := "-Xbootclasspath:jrex64\\lib\\rt.jar;" +
// add all libs
"jrex64\\lib\\";
args := []string{"-verbose", libs, "-cp Ganesha_lib\\*", "-jar Ganesha.jar"}
attr := &os.ProcAttr{
"",
nil,
[]*os.File{os.Stdin, os.Stdout, os.Stderr},
&syscall.SysProcAttr{}} //CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, }
}
proc, err := os.StartProcess(name,args,attr);
if err != nil {
log.Fatalf("start process: %v", err)
}
_, err = proc.Wait();
if err != nil {
log.Fatalf("wait: %v", err)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论