Start a Java application asynchronous
-
Hi at all!
I'm trying to start a Java application from Ruby. I just want to start it. I'm not waiting for results and it doesn't matter how long the application takes.
So, I wrote
output = system("java -jar " + File.dirname(__FILE__) + "/Model2GCode.jar " + fileForJava)
It opens the cmd just for a half of a second. Nothing else happens.
When I write "java -jar " + File.dirname(FILE) + "/Model2GCode.jar " + fileForJava" in the command line, everything is fine.
Do you have an idea, what could be the problem? I though, system() just starts the cmd and write the content... ?!So, it should be same, as when I write it by myself in the cmd.
Thanks for your help!
-
Try doing a temporary change to the jar's directory thus ?
odir=Dir.pwd Dir.chdir(File.dirname(__FILE__)) output = system("java -jar " + "Model2GCode.jar " + fileForJava) Dir.chdir(odir)
I've not tested it -
Oh TIG, you are the best! Thanks a lot!
Why your version works, and my version not?
@tig said:
Try doing a temporary change to the jar's directory thus ?
odir=Dir.pwd Dir.chdir(File.dirname(__FILE__)) output = system("java -jar " + "Model2GCode.jar " + fileForJava) Dir.chdir(odir)
I've not tested it -
I've found that running a jar with a full-file-path fails, but running it by name when already in its folder will work - not exactly sure why, but it works - presumably because '-jar' only expects a file name and not a full-file-path ?
-
@tig said:
I've found that running a jar with a full-file-path fails, but running it by name when already in its folder will work - not exactly sure why, but it works - presumably because '-jar' only expects a file name and not a full-file-path ?
Ah okay! Now, a further question... the java app starts fine. But Sketchup is waiting for the result... so, what can I do, to solve this?
-
Try:
path = File.dirname(__FILE__) cmd = 'java -jar '<< File.join(path,'Model2GCode.jar').inspect << ' ' << fileForJava UI.openURL(cmd)
The paths need to be quote delimited, I think.
Also if
fileForJava
is a filepath string in the same location, then:path = File.dirname(__FILE__) cmd = 'java -jar '<< File.join(path,'Model2GCode.jar').inspect << ' ' << File.join(path,fileForJava).inspect UI.openURL(cmd)
P.S.: Use the
<<
string append method, rather than the+
concat method. -
I take the point about quoting the paths, to avoid the change-directory workaround.
BUT I don't think UI.openURL(xxxx) will work with passed arguments
It needs a file name or path.
Although it would then execute the .jar file OK, I think any 'arguments' will be missed off...
Another way is to make something like a .cmd file, [or .command for MAC], add the whole line [with quoted arguments etc] into that... and the use UI.openURL() on that file - it should then execute and work with those passed arguments -
@tig said:
I take the point about quoting the paths, to avoid the change-directory workaround.
It could, but it was to avoid a situation, where the jar file is still working away, and Ruby changes the working directory back to the default.
There is another topic where you (TIG) describe how to write out a command file and execute it with
UI.openURL
. -
@dan rathbun said:
There is another topic where you (TIG) describe how to write out a command file and execute it with
UI.openURL
. -
@thomthom said:
@dan rathbun said:
There is another topic where you (TIG) describe how to write out a command file and execute it with
UI.openURL
.Puh, this sounds complicated!
I think, I will try Dans version and pass the arguments via temp. text file. This should be independent of the operation system...
Thanks for your ambitious help!!
-
@dan rathbun said:
Try:
path = File.dirname(__FILE__) > cmd = 'java -jar '<< File.join(path,'Model2GCode.jar').inspect << ' ' << File.join(path,fileForJava).inspect > UI.openURL(cmd) >
P.S.: Use the
<<
string append method, rather than the+
concat method.Hm, nothing hapens, when I tried this... no error from ruby, no opening window for the java... I'm a little bit confused?!
UI.openURL: "The openURL method is used to open the default Web browser to a URL." => are you sure, that I have to use UI.openURL?
-
As I explained... Dan's idea of opening [executing] a file, can't work by passing a 'command' or even an exectable with following arguments, it will only work if you pass it a file.
SoUI.openURL(full_url)
opens that web-page in the default browser.
AndUI.openURL('file:///'<<full_path_to_file)
opens that file in its default application, so if it's a .txt file then Notepad opens it, if it's a .doc file then Word opens it and so on [for a PC at least].
If it's an 'executable' then it 'runs' - these kinds of file include .exe, .cmd, .bat, .vbs etc on a PC [.command on a MAC etc].
Some executables take arguments when they are run from a 'shell'/'console'/'terminal' - e.g. in a PC command-shell typingNotepad[.exe]
opens that program with a new empty/untitled window; butNotepad "txt_file"
would open that file if it exists, or if it doesn't exist it asks you if you want to make it...
BUT you CAN'T pass arguments withUI.openURL()
So
UI.openURL("Notepad.exe")
will open an instance of 'Notepad' [true]
UI.openURL("\"Notepad.exe\" \"path_to_my_txt_file\"")
will fail [false]
UI.openURL('file:///'<<"path_to_my_txt_file")
will open that existing txt file with Notepad [true] or it will fail [false] if that txt file doesn't exist.
Usingsystem(commands)
in Ruby should give similar results to typing the exact same text into a command-shell - hence Dan's advice to 'quote' arguments - because 'spaces' in file paths will be taken as the start of a new argument otherwise and mess you up... So using
system(system("\"Notepad.exe\" \"path_to_test.txt\""))
is the same as using the very same strings inside a command-shell... BUT this runs as part of the Ruby thread, and Ruby will wait for it to complete...The way to pass arguments to an external executable, that runs independently of Ruby once it's started, is to run it as something like a .cmd/.bat [.command on MAC]. You can't avoid the startup black PC window [although you can reduce it to a flicker by having one .cmd file to start another main .cmd file, the first opens and closes almost instantaneously while the second then runs silently].
So you can write a temporary .cmd' file [etc] then useUI.openURL('file:///'<<path_to_cmd_file)
to run it [also changing directory briefly to the file's folder does allow you to 'open' it 'by name only'...]
If you use some other kinds of executables like .jar or .vbs these can be set to run 'silently' - however, passing arguments to them is then awkward [although you could 'write' a temporary .vbs file etc containing ALL of the info needed to complete things*, or perhaps use an .ini. file containing the data needed by the .jar to read in for that to do it's stuff; on a MAC you would use an AppleScript or equivalent].
*For a 'silent' VBS solution you would use something like this line of code that you 'puts' into a 'temp.vbs' file...
createobject("wscript.shell").RUN "java -jar \"full_path_to_Model2GCode.jar\" \"full_path_to_fileForJava\"", 0, False
Obviously you need to adjust it for you own full file paths/names etc...
Then in Ruby you'd useUI.openURL('file:///'<<"full_path_to_temp.vbs")
to run it - and it then executes asynchronously, quite separate from Ruby...
Advertisement