Приложението, работещо с os.exec, не зарежда правилно java библиотеките

Наистина ще съм благодарен, ако ми помогнете. Пренаписвам прост стартер на Minecraft от Java към Go. Всичко е добро, с изключение на едно нещо. Имам функция за стартиране, която се изпълнява с помощта на os.Exec тази команда:

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/*"

Може би това е защото цитирах низ "/minecraft/bin/*" с функцията strconv.Quote() или поради звездичка. Наистина не знам какво става. А, между другото, командата os.exec е изпълнена, но е правилна (прочетох я в stdout с fmt за целите на отстраняването на грешки).

програма:

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)
}

person Community    schedule 17.12.2014    source източник
comment
Вашата minecraft директория наистина е под основната директория (/)? Не е във вашата домашна директория?   -  person RealSkeptic    schedule 17.12.2014
comment
Добре, една секунда. Не, директорията е на /home, разбира се.   -  person    schedule 17.12.2014
comment
Трябва да държите аргументите разделени: arg12 := "--version 1.6.4" става arg12 := "--version" и arg13 := "1.6.4"   -  person topskip    schedule 17.12.2014
comment
Прикачен е и код.   -  person    schedule 17.12.2014
comment
@topskip, благодаря, сега ще пробвам.   -  person    schedule 17.12.2014
comment
О, и tweakclass също.   -  person    schedule 17.12.2014
comment
И не трябва да цитирате аргументите. Това е черупково нещо.   -  person topskip    schedule 17.12.2014
comment
Да, работи! @topskip, много благодаря за помощта! Винаги правя глупави грешки...   -  person    schedule 17.12.2014
comment
@topskip съжалявам, написах отговора си, преди да видя редакциите и вашите коментари. Ако напишете отговор, приет от OP, ще изтрия моя.   -  person VonC    schedule 17.12.2014
comment
@VonC Вашият отговор изглежда добре (с изключение на това, че съм объркан с двойните кавички), така че няма нужда от друг отговор.   -  person topskip    schedule 17.12.2014


Отговори (1)


Въпросът „Правилно предаване на аргументи към Go Exec“ споменава:

exec.Command(...) добавя двойни кавички към параметрите, ако има интервали в тях, така че трябва да избягвате \" само там, където имате нужда.

Във вашия случай -cp "/minecraft/bin/*" ще бъде предадено на exec.Command като два отделни параметъра.

Ако имате нужда от кавички в рамките на един параметър, можете да използвате низов литерал, за да ги запазите (както е коментирано в "Как се добавят интервали към exec.command в golang").

Но ако във вашия случай имате нужда cp (classpath) да бъде изразходван от обвивката (както е споменато в "двойни кавички, избягващи в golang exec"), след което премахнете кавичките:

exec.Command(..., "-cp", `/minecraft/bin/*`, ...)
person VonC    schedule 17.12.2014