#2584 Fan command from a Fantom process Failing

JohnNuccio Mon 12 Dec 2016

I am trying to call a fan command from a Fantom process. This is the error it runs from Fantom, it runs correctly from the command line. What do you think the problem could be?

using util

class Main {

 Void main(){
buf := Buf()

Process() {
	command = ["fan <pod>::<type>.<method>"]
	out = buf.out 
}.run.join

outStr := buf.flip.readAllStr

 }	
} 

This is the error I am getting

sys::IOErr: java.io.IOException: Cannot run program "fan <pod>::<type>.<method>": CreateProcess error=2, The system cannot find the file specified
java.lang.ProcessBuilder.start (Unknown)
fan.sys.Process.run (Process.java:141)
PDFCommandLine::Main.main (Main.fan:10)
java.lang.reflect.Method.invoke (Unknown)
fan.sys.Method.invoke (Method.java:559)
fan.sys.Method$MethodFunc.callOn (Method.java:230)
fan.sys.Method.callOn (Method.java:139)
fanx.tools.Fan.callMain (Fan.java:185)
fanx.tools.Fan.executeType (Fan.java:147)
fanx.tools.Fan.execute (Fan.java:41)
fanx.tools.Fan.run (Fan.java:308)
fanx.tools.Fan.main (Fan.java:346)

Alex Bible Mon 12 Dec 2016

Hey John,

I ran into this same issue, see the following for the fix:

using util

class Main {

Void main(){ buf := Buf()

Process() {

command = ["fan", "<pod>::<type>.<method>"] out = buf.out }.run.join

outStr := buf.flip.readAllStr

} }

Note the separation between fan and the command line arguements. I ran into this issue with "netstat -tl", it needed to be ["netstat", "-tl"] as commands cannot contain spaces.

JohnNuccio Mon 12 Dec 2016

Yes your solution MassChaosTheory works for commands like netstat -an, ping google.com, etc. But it doesn't work for fan commands.

When I echo(it.env) I can see the correct Fantom Env variable. I wonder if this might just be a Fantom bug.

SlimerDude Mon 12 Dec 2016

I think the issue is that there is no Windows file called fan, only fan.bat!

It is only the Windows command prompt that interpolates fan and looks for executable extensions, .com, .bat, .cmd, .exe, etc...

Note that experience with the BedSheet proxy tells me that the new fan.bat launches Java in separate process and the batch file finishes straight away; so you don't actually receive any output from the Process class, even though the Fantom program ran.

Instead you need to compose a command that launches the Java process yourself. Something like:

C:\> java -cp %FAN_HOME%\lib\java\sys.jar fanx.tools.Fan <pod>::<type>.<method>

Here's a little snippet from BedSheet that does just that in a X-Plaform manner:

static Process fanProcess(Str[] cmd) {
    homeDir   := Env.cur.homeDir.normalize
    classpath := (homeDir + `lib/java/sys.jar`).osPath
    args      := ["java", "-cp", classpath, "-Dfan.home=${homeDir.osPath}", "fanx.tools.Fan"].addAll(cmd)
    return Process(args)
}}

Use fanProcess() like this:

process := fanProcess(["<pod>::<type>.<method>", "arg1", "arg2"])

Note the above requires java to be on your PATH.

JohnNuccio Mon 12 Dec 2016

Thank you so much SlimerDude! This has resolved my issue.

SlimerDude Mon 12 Dec 2016

This has resolved my issue.

That's cool.

MassChaosTheory has a good point though - I've fallen foul of that myself; if I have a simple cmd with no spaces in the args, like netstat -tl, it's very awkward to write:

pro := Process(["netstat", "-tl"])   // too much punctuation!

As you're tempted to just pass in the one string, which doesn't work. So a quick tip that I often do, is:

pro := Process("netstat -tl".split)  // easy to write

Which splits the string up into an List based on whitespace!

JohnNuccio Tue 13 Dec 2016

Nice, thanks for the Pro Tip!

Login or Signup to reply.