cannot run/get output from runtime.getruntime.exec() (android java) - java

I have a php executable native binaries that came from some php server apps in play market, and I tried them on my tablet using a shell app.
I'm creating a new app and trying to run it and receive the output but it doesn't work.
I've a function that does copy the assets to the device. I also have some code to test that they are there properly
File file4 = new File(getFilesDir().getAbsolutePath()+"/php");
file4.setExecutable(true);
s+=file4.getName();
s+=file4.exists();
s+=file4.canExecute();
s+=file4.length();
it does say correct filename exists, is executable and correct file length.
Now, I try to run it it doesnt give me the php output.
I've tried php -v for version output, doesn't work.
I've tried php phpfile.php >> file.html and read the file, doesn't work.
I've tried with -f and also without -f but it doesn't work.
Lastly, I tried giving the parameters and working dir separately to .exec and still it gives no proper output
When I tried runtime.getruntime.exec with other commands like /bin/cmd/ls ... it gives a correct output.
The php binaries do work, I've tried 2 of them on my device, none work in my app.
I would appreciate help.
s+=runphp();
public String runphp(){
try {
String prog= "./php";
String[] env= { "-f", getFilesDir().getAbsolutePath()+"/phprun.php"}; // ">>","phpoutput.txt"
File dir= new File(getFilesDir().getAbsolutePath());
Process p = Runtime.getRuntime().exec(prog,env,dir);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=null;
String output="";
while ((line = in.readLine()) != null) {
output += line;
}
in.close();
p.waitFor();
return output;
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
The function does work for other commands.

The method Runtime.exec(String prog, String[] envp, File directory) requires you to give environment in the form name=value in the String[] envp.
But you are using it to pass arguments to your php program.
Use the following method instead,
Process exec (String[] progArray, String[] envp, File directory);
and pass all your command line arguments too in the first array itself.
Your command should look like:
String[] progArray= {"./php", "-f", getFilesDir().getAbsolutePath()+"/phprun.php"}; // ">>","phpoutput.txt"
File dir= new File(getFilesDir().getAbsolutePath());
Process p = Runtime.getRuntime().exec(progArray,null,dir);

Related

Java FFmpeg no output

I´ve run into problem. I want to convert video using ffmpeg but it gives me no output
public void convert(String inputFile, String outputFile, String ... optionalParams) {
ProcessBuilder processBuilder = new ProcessBuilder("ffmpeg", "-i", "\"" + inputFile.trim() +"\"", "\""+ outputFile.trim() + "\"");
DownloadRecord downloadRecord = table.getItems().get(0);
downloadRecord.setStatus("Downloading");
// Try to execute process
try {
// Set the working directory
processBuilder.directory(new File(workingDirectory));
//Start the process
Process process = processBuilder.start();
// Read the output from cmd
BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader ra = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line;
String errline;
while ((line = r.readLine()) != null) {
System.out.println(line);
}
while ((errline = ra.readLine()) != null) {
System.out.println(errline);
}
process.waitFor();
System.out.println("the end");
} catch(IOException | InterruptedException e) {
System.out.println(e.toString());
}
}
I've been searching on stackoverflow and find some solutions, none worked. What I tried and figured out so far
No output or error output
I tried to remove backslashes from ProcessBuilder, it
also gives me no output
I tried to let the program running, but it never finishes
I tried to use full path to the ffmpeg, no changes
I tried to run the video, no error
I am using
Netbeans IDE so I tried clean and rebuild project, no change
process also never finishes
I would like from it an output. Does someone know what I am doing wrong here ?
I fixed it by reinstalling the ffmpeg. Just went ffmpeg website downloaded newest version, replaced files in folder and it works
Edit:
It just works for files with less thatn 2 mins for some reason, more thatn 2 mins files are behaving like this
I start converting, it will not convert entirely until program runs. After I exit the program it will finish. It´s strange behaviour.

java execute external program and read its output

I want to read output from ADB logcat (https://developer.android.com/studio/command-line/adb). I have such code (test):
try {
Process p = Runtime.getRuntime().exec("sh -c adb logcat");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while(true) {
String s = bufferedReader.readLine();
if(s == null) {
continue;
}
System.out.println("From process: " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
But this prints nothing. If I execute this:
Process p = Runtime.getRuntime().exec("sh -c ls");
It works.
Okay, I too fast asked the question on SO.
I read error stream instead of inputstream and I find out that cannot find program ADB. Need to provide full path:
ProcessBuilder processBuilder = new ProcessBuilder("/home/UserName/Soft/Android/Sdk/platform-tools/adb", "logcat");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
But on another computer path is different. Also you can on every computer make symbolic link and in code use as path simply "adb":
sudo ln -s /home/UserName/Soft/Android/Sdk/platform-tools/adb /bin/adb
ProcessBuilder processBuilder = new ProcessBuilder("adb", "logcat");
This is not the best solution, partially resolves problem. Would be great without making symbolic link, using simply "adb" in instantiating ProcessBuilder object. Because in every disk location on my computer I can use ADB in terminal, it is visible but in this code no. In Windows I know that this is in System Environments > PATH. In linux I wrote command "printenv" but I don't see anything with android & adb.

Java can't save Output Stream to a file

This code works fine on Computer A and doesn't work on Computer B ... I can't understand Why..
Nothing Exceptions or anything else ....On Computer A log file was created , on computer B log file was't created.
Computer A and B have the same Java version...
Do you have any ideas?
String str = "cmd /C dir tools>1.log";
try {
Runtime.getRuntime().exec(str);
} catch (Exception e) {
e.printStackTrace();
}
PS
this code works fine on both computers
String str = "cmd /C dir tools";
You have to open the process' output stream to save the output to a file correctly.
You can do this by creating a Process object and saving that to a file:
Process p = Runtime.getRuntime().exec(str);
InputStreamReader reader = p.getInputStream();
BufferedReader buffer = new BufferedReader(reader);
String line = null;
while ((line = buffer.readLine() != null) {
//write stuff to file here
}
Going on what SLaks said -- it is your best bet to use the built-in file APIs.
Here is a link for a general tutorial
Using these APIs will take out any strange environment issues from Computer A to B...to C and so on.

How can I execute unix sort command (/usr/bin/sort) from Java?

I am hoping to leverage the unix sort command to sort a large text file in Java. I've tried executing sort with the process builder, but with no luck. However when I print the exact command it is going to execute and copy and paste it into the terminal, it works fine.
So far I've tried executing with /bin/sh -c "", making sure the directory the input file is and where the output file will be is fully permissioned (chmod 777) but with no luck.
Here is the code (if it looks funny, note is using some functions found in Guava)
File inputFile = new File(inputFileName);
//build the command (optional number of sort columns)
List<String> command = new LinkedList<String>();
command.addAll(ImmutableList.<String>of("sort","-t"+delimiter));
for (int i : sortFieldPositions) {
command.add("-k"+i+","+i);
}
command.addAll(ImmutableList.<String>of(inputFileName,">",outputFileName));
//for debugging: output the command that will be executed
System.out.println("Executing: "+Joiner.on(" ").join(command));
//construct and start the process
Process process = new ProcessBuilder(command).redirectErrorStream(true).directory(inputFile.getParentFile()).start();
//for debugging: save process output
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder outputStringBuilder = new StringBuilder();
for (String line; (line = bufferedReader.readLine()) != null; /*reading taking place in check */) {
System.out.println("FROM PROCESS: "+line);
outputStringBuilder.append(line);
}
bufferedReader.close();
if (process.exitValue() != 0) {
//something went wrong
throw new RuntimeException("Error code "+process.exitValue()+" executing command: "+Joiner.on(" ").join(command)+"\n"+outputStringBuilder.toString());
}
Unfortunately this does not work, with the following output:
Executing: sort -t, -k2,2 -k1,1 /tmp/java/TestDataSorterImporterInput.txt /tmp/java/TestDataSorterImporterOutput.txt
FROM PROCESS: sort: stat failed: >: No such file or directory
Edit: It may be helpful to note that if I remove saving the output (> outputfile) from the command, then the command executes without complaint and the sorted version appears in the output from the Processes' input stream)
It is the shell that knows how to perform output redirection. The sort program cannot do it on its own. So if you want redirection, you need to do /bin/sh -c ... to let she shell into the loop.
(You write that you have tried this, but something else must have gone wrong with that).
Try this:
String whatever = "filename";
Process p = Runtime.getRuntime().exec("sort -t -k2 2 -k1 1 " + whatever);
See this site.
Process process = new ProcessBuilder("/bin/bash", "-c", "sort -t'|' -k2").start();

How to run a .jar file from inside another java program?

i have a .jar file, which I can run on the command line:
java -jar myFile.jar argument1
I want to save the output of this .jar as a String variable inside another java program.
How can I do it?
I tried including myFile.jar as a reference in my program, and doing myFile.main(new String{"argument1"}) in my program. But this just prints the results to console, I can't use the results in my program.
Hope this is not too confusing.
I
Running Jar file require you to have the jar file included in your class path. This can be done at run time using URLClassLoader. Simply construct a URLClassLoader with the jar as one of the URL. Then call its forClass(...) if you know the class name (full name of course). Or inspect the manifest file using its 'findResources(String name)'.
Once you get the class, you can use reflection to get its static method main.
Seeing your question again, you know the class name, so if you are sure the jar file in already in the class path, then you can just call it as you tried.
II
To capture the output, you can call System.setOut(PrintStream out) and System.setErrPrintStream out) to change the print stream. You can pass the printstream that you create. Like this:
ByteArrayOutputStream BAOS = new ByteArrayOutputStream();
PrintStream MyOut = new PrintStream(BAOS);
System.setOut(MyOut);
// Do something to have something printed out.
...
String TheCaptured = new String(BAOS.toByteArray());
Hope this helps.
If you can't include the other jar,
you can use something like that
Runtime re = Runtime.getRuntime();
BufferedReader output;
try{
cmd = re.exec("java -jar MyFile.jar" + argument);
output = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
} catch (IOException ioe){
ioe.printStackTrace();
}
String resultOutput = output.readLine();
I know my code isn't perfect like the catching exception, etc but I think this could give you a good idea.
Being a Jar file, you can add it to your class path and call the functionality of the program your self. You might need to know more about the logic behind the Jar to use it without having it output the information..
I believe what you are looking for is how to shell execute the Jar archive. An example can be found here.
Take a look at ProcessBuilder:
http://java.sun.com/javase/6/docs/api/java/lang/ProcessBuilder.html
It effectively creates an operating system process which you can then capture the output from using:
process.getInputStream().
The line:
processbuilder.redirectErrorStream(true)
will merge the output stream and the error stream in the following example:
e.g.
public class ProcessBuilderExample {
public ProcessBuilderExample() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "gscale.jar");
pb.redirectErrorStream(true);
pb.directory(new File("F:\\Documents and Settings\\Administrator\\Desktop"));
System.out.println("Directory: " + pb.directory().getAbsolutePath());
Process p = pb.start();
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
for (String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println( line ); // Or just ignore it
}
p.waitFor();
}
}

Categories

Resources