Reputation: 33
I want to execute the following command via script through Eclipse.
java -cp /home/pallavi/KeplereeWorkspace/trace/target/classes:/home/pallavi/git/thesis-2016/Soot_Instrumentation/sootOutput org.employee.Employee
I run it like:
Runtime.getRuntime().exec("./src/main/resources/Intrumentation_Execution.sh");
The program "Employee" is an interactive program which means that user needs to select options and different output/processes may occur. If I use BufferedReader I see only the initial printlines and no user input can be given. when I run the Intrumentation_Execution.sh from terminal everything works fine. However, I need to run it through another Java Program.
Also note, I cannot call the main method of Employee in my execution class because I am building an automated tool for which Employee is just a test case per say.
Upvotes: 1
Views: 92
Reputation: 10555
Create a bridge to speak to the Java process which is started from the shell script. Something like the below:
startreader.sh
#!/bin/bash
echo "" > inputbridge.txt
tailf inputbridge.txt | java SampleRead
SampleRead.java
import java.util.Scanner;
public class SampleRead {
public static void main(String [] args) {
Scanner scanner = new Scanner(System.in);
int readValue = 0;
while((readValue = scanner.nextInt()) != 5) {
System.out.println("Send me something other than " + readValue);
}
System.out.println("Good job. Bye");
}
}
NumberGenerator.java
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class NumberGenerator {
public static void main(String [] args) throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder("./startreader.sh");
Process process = processBuilder.start();
Scanner processStreamReader = new Scanner(process.getInputStream());
String processInputString = null;
do {
try(FileWriter fileWriter = new FileWriter("inputbridge.txt", true)) {
fileWriter.write(((int)(Math.random() * ((10 - 1) + 1)) + 1) + "\n");
} catch(IOException e) {
e.printStackTrace();
}
processInputString = processStreamReader.nextLine();
System.out.println(processInputString);
} while(processInputString.startsWith("Send me something other than"));
}
}
Steps to run:
SampleRead.java
and NumberGenerator.java
startreader.sh
java NumberGenerator
Output
[jjithin@sjawanpopst8 java]$ java NumberGenerator
Send me something other than 1
Send me something other than 6
Send me something other than 8
Send me something other than 4
Good job. Bye
[jjithin@sjawanpopst8 java]$ cat inputbridge.txt
1
6
8
4
5
How this works:
The bridge between the NumberGenerator
and SampleRead
is inputbridge.txt
file generated through startreader.sh
. When NumberGenerator
is run, it executes startreader.sh
which generates inputbridge.txt
and empties it. The next stage in startreader.sh
is to do tailf
on inputbridge.txt
file. Any new line written to this file will become the input to SampleRead
via tailf
process.
When NumberGenerator
randomly picks a number and sends to SampleRead
by writing to inputbridge.txt
, it gets received by SampleRead
, checks if it is of value 5. Other than value 5 will output "Send me something..." which is read by NumberGenerator
through the ProcessInputStream
.
This approach should be enhanced with check for java process existence after executing the shell script. Moreover, the tailf
process won't exit until it is killed manually. Hence, tailf
could be replaced with another proxy java application, which has a communication protocol with NumberGenerator
kind of application to know when to end execution. You may consider using Sockets
instead of files if developing a java proxy application.
Upvotes: 1