应用程序使用os.exec运行时无法正确加载Java库。

huangapple go评论89阅读模式
英文:

Application running using os.exec doesn't load java libraries properly

问题

我很乐意帮助你。我正在将一个简单的Minecraft启动器从Java重写为Go。一切都很好,只有一个问题。

我有一个使用os.Exec执行的start函数,执行以下命令:

java -Xincgc -Xmx1024M -Djava.library.path="/minecraft/bin/natives/" -cp "/minecraft/bin/*" -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true net.minecraft.launchwrapper.Launch --username user --session session --version 1.6.4 --gameDir "/minecraft" --assetsDir "/minecraft" --tweakClass cpw.mods.fml.common.launcher.FMLTweaker

通过bash或cmd运行这个命令一切正常,但是当使用Go函数执行时,返回以下内容:

Could not find or load main class net.minecraft.launchwrapper.Launch

我认为os.exec(Command)无法正确解释命令的这一部分:

-cp "/minecraft/bin/*"

可能是因为我使用了strconv.Quote()函数引用了字符串"/minecraft/bin/*",或者是因为星号的原因。我真的不知道发生了什么。顺便说一下,os.exec运行的命令是正确的(我使用fmt将其输出到stdout进行调试)。

程序:

func start(login string, session string, ram string) {
//启动游戏

app := "java"
arg0 := "-Xincgc"
arg1 := "-Xmx" + ram + "M"
arg2 := "-Djava.library.path=" + strconv.Quote(filepath.FromSlash(client+"bin/natives/"))
arg3 := "-cp"
arg4 := strconv.Quote(filepath.FromSlash(client + "bin/*"))
arg5 := "-Dfml.ignoreInvalidMinecraftCertificates=true"
arg6 := "-Dfml.ignorePatchDiscrepancies=true"
arg7 := "net.minecraft.launchwrapper.Launch"
arg8 := "--username"
//arg9是login
arg10 := "--session"
//arg11是session
arg12 := "--version 1.6.4"
arg13 := "--gameDir"
arg14 := strconv.Quote(filepath.FromSlash(client))
arg15 := "--assetsDir"
arg16 := strconv.Quote(filepath.FromSlash(client + "assets"))
arg17 := "--tweakClass cpw.mods.fml.common.launcher.FMLTweaker"

cmd := exec.Command(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
fmt.Println(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
}
英文:

I would really appreciate if you helped me. I'm rewriting a simple Minecraft launcher from Java to Go. Everything is good, in exception of one thing.
I have a start function which executes using os.Exec this command:

java -Xincgc -Xmx1024M -Djava.library.path="/minecraft/bin/natives/" -cp "/minecraft/bin/*" -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true net.minecraft.launchwrapper.Launch --username user --session session --version 1.6.4 --gameDir "/minecraft" --assetsDir "/minecraft" --tweakClass cpw.mods.fml.common.launcher.FMLTweaker

Everything is fine running this through bash or cmd, but when executed with Go function it returns the following:

Could not find or load main class net.minecraft.launchwrapper.Launch

I think os.exec(Command) cannot properly interpet this part of command:

-cp "/minecraft/bin/*"

Maybe that's because I quoted string "/minecraft/bin/*" with strconv.Quote() function or because of asterisk. I really don't know what's heppening. Ah, btw, the command os.exec has run is correct, though (I read it in stdout with fmt for debugging purposes).

program:

func start(login string, session string, ram string) {
//start game

app := "java"
arg0 := "-Xincgc"
arg1 := "-Xmx" + ram + "M"
arg2 := "-Djava.library.path=" + strconv.Quote(filepath.FromSlash(client+"bin/natives/"))
arg3 := "-cp"
arg4 := strconv.Quote(filepath.FromSlash(client + "bin/*"))
arg5 := "-Dfml.ignoreInvalidMinecraftCertificates=true"
arg6 := "-Dfml.ignorePatchDiscrepancies=true"
arg7 := "net.minecraft.launchwrapper.Launch"
arg8 := "--username"
//arg9 is login
arg10 := "--session"
//arg11 is session
arg12 := "--version 1.6.4"
arg13 := "--gameDir"
arg14 := strconv.Quote(filepath.FromSlash(client))
arg15 := "--assetsDir"
arg16 := strconv.Quote(filepath.FromSlash(client + "assets"))
arg17 := "--tweakClass cpw.mods.fml.common.launcher.FMLTweaker"

cmd := exec.Command(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
fmt.Println(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
}

答案1

得分: 1

正确传递参数给Go Exec”这个问题提到:

如果参数中有空格,exec.Command(...)会在参数周围添加双引号,所以你只需要在需要的地方转义\"

在你的情况下,-cp "/minecraft/bin/*"会作为两个独立的参数传递给exec.Command

如果你需要在一个参数中使用引号,你可以使用string literal来保留它们(正如在“How do you add spaces to exec.command in golang”中所评论的)。

但是,如果在你的情况下,你需要shell来展开cp(classpath)(如“double quotes escaping in golang exec”中所提到的),那么去掉引号:

exec.Command(..., "-cp", `/minecraft/bin/*`, ...)
英文:

The question "Properly pass arguments to Go Exec" mentions:

> exec.Command(...) adds double quotes to the parameters if there is spaces in them, so you only need to escape \" where you need them.

In your case, -cp "/minecraft/bin/*" would be passed to exec.Command as two separate parameters.

If you need quotes within one parameter, you could use a string literal to keep them (as commented in "How do you add spaces to exec.command in golang").

But if, in your case, you need the cp (classpath) to be expended by the shell (as mentioned in "double quotes escaping in golang exec"), then remove the quotes:

exec.Command(..., "-cp", `/minecraft/bin/*`, ...)

huangapple
  • 本文由 发表于 2014年12月17日 22:59:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/27528430.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定