Java process.getRuntime().exec() never stop his job - java

Hello guys im writing a web app in java with servlet, but i need for a job to use python, so im using Process.getRuntime().exec() for call the script.
My web app is a survey and between client compile it we take a photo of him.
I need python for deepface, for detection his emotion, and write all the results in a pdf file (what he choose, photos and detection of emotion result).
For 7 question in the survey the script works fine, when i put 8 question he never stop his job (the script working when isn't called from java i tested it).
Can you help me for understand how i can find the error? This process has got a limit of resources or something like that?
Process p = Runtime.getRuntime().exec("python "+rootPath+"\\DeepFaceLearning\\TestFace.py "+nomeFile);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String temp ="";
while((temp = stdInput.readLine()) != null) {
System.out.println(temp);
}
For python the script is very long, but i think the problem is java beacuse he works fine when i run the script from command line with 40 questions.
I need to add 21 question in total.
Script python:
take a file read it and save the questions,reason e photos in a variables
analyze all photos
wirte all this information on a pdf
save pdf in db
Edit: java enter into script but don't complete all the job.

If the your python is working for 7 the same way as for 8 question, you could try to read the inputstream in other Thread.
Like:
...
new Thread(new Runnable(){
#Override
public void run(){
BufferedReader stdInput = new BufferedReader(newInputStreamReader(p.getInputStream()));
String temp ="";
while((temp = stdInput.readLine()) != null) {
System.out.println(temp);
}}).start();

Related

Passing data from Java process to a python script

I call a external Python script as Java process and want to send data to this. I create a process and try to send a string. Later the python script should wait for a new input from Java, work with this data and wait again(while true loop).
Python Code (test.py):
input = input("")
print("Data: " + input)
Java Code:
Process p = Runtime.getRuntime().exec("py ./scripts/test.py");
BufferedWriter out = new BufferedWriter(new
OutputStreamWriter(p.getOutputStream()));
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
System.out.println("Output:");
String s = null;
out.write("testdata");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
The process and output of simple prints works, but not with input and BufferedWriter.
Is it possible to send data to this python input with a Java process?
I read from other solutions:
create a Python listener and send messages to this script
import the external script to Jython and pass data
Are this better solutions to handle my problem?
use Process class in java
what is process class ?
this class is used to start a .exe or any script using java
How it can help you
Create your python script to accept command line variables and send your data from java class to python script.
for Example:
System.out.println("Creating Process");
ProcessBuilder builder = new ProcessBuilder("my.py");
Process pro = builder.start();
// wait 10 seconds
System.out.println("Waiting");
Thread.sleep(10000);
// kill the process
pro.destroy();
System.out.println("Process destroyed");
Later the python script should wait for a new input from Java
If this has to happen while the python process is still a subprocess of the Java process, then you will have to use redirection of I/O using ProcessBuilder.redirect*( Redirect.INHERIT ) or ProcessBuilder.inheritIO(). Like this:
Process p = new ProcessBuilder().command( "python.exe", "./scripts/test.py" )
.inheritIO().start();
If the python process is going to be separate (which is not the case here, I think) then you will have to use some mechanism to communicate between them like client/server or shared file, etc.

Fetching the logs from another Java Application

in a project I need to execute a java application from another java application. So far so good. Now I am stuck at the point, where the former needs to fetch the latters logs from the console.
The execution of the second is handled by the following snipped of code:
ArrayList<String> commands = new ArrayList<>();
commands.add("javaw");
commands.addAll(data.returnPropertiesAsPrefixedStringList());
commands.add("-cp");
commands.add(data.getClasspathJar().toString());
commands.add("[PathToMainClass]");
//data.getArgs for example contains the path to the second java (jnlp) file
commands.addAll(data.getArgs());
ProcessBuilder java = new ProcessBuilder().inheritIO().command(commands);
Process start = java.start();
How can I now fetch the logs "start" writes to the console? As I did not quite know what I had to search for, I did not manage to find fitting answers.
Edit:
I have tried getting the logs like that, but it did not work. The Logs weren't recognised at all.
Process start = java.start();
BufferedReader input = new BufferedReader(new InputStreamReader(start.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
System.out.println("It Did Work: " + line);
}
Thank you in advance for your help.
-IHaveNoClue
Process has a getInputStream() operation, so you could use an inputstream reader to access this data. Also maybe this discussion will help you: printing-runtime-exec-outputstream-to-console

Using SSMTP and ProcessBuilder

I'm currently working on a project for school and I'm trying to use sSMTP to send emails from java to a user using a text file. Executing from the command line ssmtp email#gmail.com < msg.txt works just fine and sends me the email with the information contained in msg.txt. However, when I try to do it in java using ProcessBuilder it doesn't send an email.
`ProcessBuilder builder = new ProcessBuilder;
builder.command("ssmtp", "email#gmail.com", "<", "msg.txt");
Process p = builder.start();`
I believe that it doesn't like where I try to pipe in msg.txt. If anyone knows a better way to do this that would be great. I haven't been able to find anything yet and am not sure how to do it myself
Instead of trying to rely on the shell's redirect functionality (which as you see doesn't work), you can just read msg.txt and write it to the process' OutputStream. It'll be the same thing, but in code (and it'll be a better solution too).
Something along the lines of
Process p = new ProcessBuilder("ssmtp").start();
PrintStream out = new PrintStream(p.getOutputStream());
String line = null;
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("msg.txt")));
while((line = in.readLine()) != null)
out.println(line);
out.close();
in.close();
However if you want to use shell redirection which I wouldn't recommend for anything serious, you need to execute the program which actually does the redirection, i.e. bash. The following should do the trick:
new ProcessBuilder("bash", "ssmtp", "email#gmail.com", "<", "msg.txt").start();
As dave_thompson_085 commented, it's even easier to do programmatic redirection. Things sure are easy these days!
new ProcessBuilder("ssmtp", "email#gmail.com").redirectInput(new File("msg.txt")).start();

Check if the desktop application is already running

I am working on a java based desktop application. One requirement is that if application is running and user try to start the application again it should do something like show some alert etc.
I used file for this, when user run the app it add some text into a file and save it somewhere on the local system and when user try to run the app again i check the file and handle the situation accordingly, but there are some issue with this, like if application is abnormally terminated i am not able to remove that file and in that case when user tries to run the app system shows alert that application is already running but actually app terminated abnormally.
I did some R&D and found that i can read windows task manager list and then i can get and check my app if it is running. it was working fine but during testing i got an issue i-e there is a software/utility in windows named "tasklist" go to "start --> run" and type tasklist it will show you the task list. if this utility is not installed on your system or removed/corrupted for some reason then this will not work and same issue occur that user can start the application more then one time. Here is code to access the taskmanager items
Process p = Runtime.getRuntime().exec(
System.getenv("windir") + "/system32/" + "tasklist.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(
p.getInputStream()));
while ((line = input.readLine()) != null) {
/*
Make the comparison here and show alert.
*/
}
Question: What is a good way to check if the app is already running? I am using Java for application, and advanced installer to create the installer of the application.
Launch the app. with Java Web Start and use the SingleInstanceService. See the demo. of the SingleInstanceService for (demo. and) example code.
am using .. advanced installer to create the installer
Note that JWS:
Is also an application installer. So I am suggesting this route as an alternative to using 'advanced installer'.
Is provided by the makers of Java (Sun/Oracle).
Check out http://ss64.com/nt/wmic.html
and try
String line;
try {
Process proc = Runtime.getRuntime().exec("wmic.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
OutputStreamWriter oStream = new OutputStreamWriter(proc.getOutputStream());
oStream .write("process where name='THE NAME OF YOUR PROCESS.exe'");
oStream .flush();
oStream .close();
while ((line = input.readLine()) != null) {
System.out.println(line);
}:
input.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
Courtesy:How to detect via Java whether a particular process is running under Windows?

java servlet, run exe file in a server to the client

I have a java servlet running in a server, plus an 'exe file' located in the same server,
i want , in respond to the client passed parameters to the servlet , to run the exe file located on the server and show it to the client , even a screen shot,,
any ideas??!! please help
You can use Process and Runtime classes
Eg :
Runtime r = Runtime.getRuntime();
Process p = r.getRuntime().exec("C:\\newfolder\\run.exe");
For taking screenshot refer to how to take sc in java
This way you can save the image and then send this image to user.
For sending image to client refer to how to send file from sever to client
these are.the pieces , you need to put them together
UPDATE 1 : to kill the exe you can use p.destroy() ( not a good implementation though, as it forcefully kills the process)
UPDATE2 : to check if the process( which is executing your exe) hence to check if the exe is running or not, you can refer to how to check if a process is running
You can run an external command in Java by the following code:
Process p = Runtime.getRuntime().exec("your_external_program_here");
You can pass in parameters as well, simply amend the above line to include what parameters you want to pass into the program.
To retrieve the 'output' of the process you need to get the input stream for the process:
InputStream output = p.getInputStream();
Note the input stream is the piped output of the process. You can then view the contents (advisable to use a buffered reader) like this:
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(output));
while ((line = reader.readLine()) != null) { ... }
Or alternatively you can look at ProcessBuilder which is easier to use :)

Categories