Executing python compiled script (.pyc) in Java - java

I have a python compiled script (script.pyc , I haven't the .py file)that work well from my windows command prompt, and I want to execute it from my Java's application.
I tried to use runtime() method :
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[] {"C:\\toto\\tools\\script.pyc" ,"arg","arg2" });
but I get an error :
Exception in thread "main" java.io.IOException: Cannot run program "C:\Nuance\VoCon Hybrid\SDK_v4_3\tools\clctodict.pyc": CreateProcess error=193, %1 n?est pas une application Win32 valid
The script work well in my terminal ("arg" is a txt file, "arg2" is the output name, and the script does its job without any problem).
I also try to launch my script with getDesktop() :
File fie = new File("C:\\toto\\tools\\script.pyc" ,"arg","arg2");
Desktop.getDesktop().open(fie);
There is no problem, but I can't add argument, so I can just see a terminal windows opening during a few second before disappearing instantly.
I have also tried to use JPython, without success too (maybe we can't use methode "execfile" on a .pyc????)

You can do something like
Process p = Runtime.getRuntime().exec(new String[]{"python.exe" ... other args)
Then you can invoke p.waitFor() to wait for the end of the process and p.exitValue() to test if the program exited successfully.
You can also get the output stream via p.getOutputStream() to retrieve the text printed by your python script
Please refer to the class documentation for further information : http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html

Just like you need a jvm to run a .class, you need a python interpreter to run a .pyc.
Try something like:
runtime.exec(new String[] {"c:\\Python26\\bin\\python.exe", "C:\\toto\\tools\\script.pyc" ,"arg","arg2" });

Related

Need to move on after java error when Python script uses subprocess to run a java program

In a python2.7 script, I'm using subprocess.call to run a java program like this:
java_command = "java -jar /path/to/java_program.jar %s %s >> %s" % (infile, outfile, logfile)
subprocess.call(java_command, shell=True)
...
#Do other stuff unrelated to this output
Most of the time, this works fine, but in some cases the java program errs:
Exception in thread "main" java.lang.NullPointerException
at MyProgram.MainWindow.setProcessing(MainWindow.java:288)
The problem is that my python script is then stalled on the subprocess.call() line and can't do the "other stuff".
Is there a way I can edit either the java_command I'm using or the way I'm using subprocess to continue the python script even when the java program hangs?
Note that I can't modify the java program's code.
I think you want the check_call method from that same package:
try:
status = subprocess.check_call(java_command, shell=True)
except CalledProcessError as e:
# The exception object contains the return code and
# other failure information.
... react to the failure and recover

Execution of Windows batch file using Java ProcessBuilder always returns exit code 0

I'm trying to execute a batch file and get the error code from it in Windows 7 Enterprise 64-bit.
My batch file is c:\test.cmd and contains a single line:-
exit 1
My code for executing the batch file is:-
public static void main(String[] args) throws Exception {
Process process = new ProcessBuilder("c:\\test.cmd").start();
System.out.println(process.waitFor());
}
The output is zero. If I try with:-
new String[] {"cmd", "/c", "c:\\test.cmd"}
the result is again zero.
There doesn't seem to be much magic to the ProcessBuilder API that I'm missing. Can anyone see where my code is going wrong?
Shouldn't I be able to capture the exit code of the batch file?
I think there is something wrong (or different) with my PC. The Apache Commons Exec project source code I downloaded failed unit tests when capturing return codes. Looks to be unsolvable on my PC and haven't found a workaround.

ProcessBuilder can't find perl

I'm trying to execute a perl script from java with the following code:
ProcessBuilder script =
new ProcessBuilder("/opt/alert-ssdb.pl");
Process tmp = script.start();
But when I execute it it returns
java.io.IOException: Cannot run program "/opt/alert-ssdb.pl": java.io.IOException: error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:488)
at scripttest.main(scripttest.java:11)
Caused by: java.io.IOException: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.<init>(UNIXProcess.java:164)
at java.lang.ProcessImpl.start(ProcessImpl.java:81)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:470)
... 1 more
about the file
ls -l alert-ssdb.pl
-rwxr-xr-x. 1 root root alert-ssdb.pl
I tried running /usr/bin/perl/ with the script as an argument and it also failed with the same exception.
/bin/ls and other simple commands run without a problem though.
Also the first line of the script is #!/usr/bin/perl
and when run on command line it works
what am I missing?
//Update:
The big picture is that I'm trying to call the script via a storm bolt and it fails at that point.
I managed to make it work by defining a python script as a bolt
using
super(python,myscript.py)
(myscript imports the storm library) and from myscript I call the perl script.
I haven't tried yet but I suppose that If I modify the perl script to be a storm bolt it will run nicely.
Try changing
new ProcessBuilder("/opt/alert-ssdb.pl");
to:
new ProcessBuilder("/usr/bin/perl", "/opt/alert-ssdb.pl");
I've had past experiences where not all my environment variables from the shell exist when using ProcessBuilder.
Edited to reflect #dcsohl's comment.

Run cmd-line in java fails

I am facing the following problem:
I am writing a java-application in Eclipse. Inside my application I want to start a cmd command:
C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/bin/connect -h
The command 'connect -h' is a an enterprise internal application which works fine.
If I would use a comand line a would have to chance my current directory like that:
cd C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/bin/
and afterwards I would just type connect -h
This works great. But I am not really shure how to execute this command within a java application.
Here they tell me how to run a cmd inside a java application:
How to use "cd" command using Java runtime?
But if I do that:
Runtime.getRuntime().exec("'C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/bin/connect' -h");
Eclipse tells me:
java.io.IOException: Cannot run program "'C:/Users/User1/Content-Integration": CreateProcess error=2, Das System kann die angegebene Datei nicht finden
at java.lang.ProcessBuilder.start(Unknown Source)
It cuts my command at "Content-Integration".
can someone help me please?
You should use the version of exec() that takes multiple args via a String array.
Runtime.exec(String s) will split your string using a tokenizer (this is why quoting the string won't work, and why you see the behaviour you do). If you resolve the executable and arguments yourself, and pass each as an array element in the above e.g.
String[] args = new String[]{"executable", "arg1", "arg2"};
Runtime.getRuntime().exec(args); // don't forget to collect stdout/err etc.
then you will bypass Runtime.exec(String s)'s splitting behaviour.
Have you tried:
Runtime.getRuntime().exec("\"C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/bin/connect\" -h");
This happens because your path contains spaces. Make sure to wrap it in "" and it will work.
Runtime.getRuntime().exec("\"C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/bin/connect\" -h");

java executing bash script, error=26 Text file busy

I've got a java code that is writing a Linux bash script out, then doing a chmod to add execute permission, then trying to execute it. I'm getting an IOException during the start of the process saying error=26, Text file busy. I've verified that the file is finished being written and the stream was closed. The chmod works fine, but I keep getting this error.
I've noticed that if I run a debugger and step through the code, it doesn't get the error, so clearly there is a timing issue involved. How can I make sure the chmod is done before I try to execute the bash script? I'd like to avoid non-reliable solutions like adding Thread.sleep(10000), and "hacky" things like putting the execution in a try/catch block inside a loop that tries until it succeeds.
I have a fair amount of code wrapping the startup of the process with listening threads, etc., but here is a simplified version of what it is doing (tried this code also and it has same result):
String[] cmd1 = {"/bin/chmod", "750", postFile };
new ProcessBuilder(cmd1).redirectErrorStream(true).start().waitFor();
String[] cmd2 = { postFile };
new ProcessBuilder(cmd2).redirectErrorStream(true).start().waitFor();
Every time after execution, the "postFile" has the correct 750 permissions, but it has not executed (due to the IOException).
For future reference, it may have been caused by an unclosed stream in this particular case, but setting permissions on a file immediately followed by running the file can cause this error too:
java.io.IOException: Cannot run program "...": error=26, Text file busy
It is a probable bug in JDK. In my case, it was caused by this snippet of code
Files.setPosixFilePermissions(Paths.get(scriptPath), set(PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.OWNER_READ));
ProcessBuilder processBuilder = new ProcessBuilder(scriptPath).directory(workingDir);
processBuilder.start();
even if nothing was editing the script file.
Are you sure it is the chmod that is responsible for the subsequent error? Could you check that you definitely close the output file before you try to run it?
If you do close it then I'm at a loss why chmod should cause that error, but you could avoid the need to run chmod by using your shell to run the script:
String[] cmd = {"bash", postfile };
I don't know if it's related but usually you need to get or redirect the ErrorStream and the InputStream (I usually get them in a ResponseStreamReader that I create, don't know about the redirecting choice).
In my service file in /etc/systemd/system/ I have directed outputs to log files:
StandardOutput=file:/home/pi/ApplicationLogs/application_l_debug.log
StandardError=file:/home/pi/ApplicationLogs/application_l_error.log
The error message disappeared when I changed permissions on the ApplicationLogs directory to write permissions to all
(chmod a+w ApplicationLogs)

Categories

Resources