1

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 Answers1

1

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/*`, ...)
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250