Search code examples
cmdfantom

Fan command from a Fantom process Failing


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?

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)

Solution

  • 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 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 successfully.

    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 that does just that in a cross-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)
    }
    

    And you can use like this:

    buf := Buf()
    fanProcess(["<pod>::<type>.<method>", "arg1", "arg2"]) {
        out = buf.out 
    }.run.join
    outStr := buf.flip.readAllStr
    

    Note the above requires java to be on your PATH.