I am trying to invoke non linux command on linux using java code. The libraries required for that command are installed on my linux machine. Here is my java code which invokes the command using Runtime.getRuntime().exec();
The command reads the borcode from the image file and decodes it and shows the value on console.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class demo {
public static void main(String args[]){
getcodes();
}
public void getCodes(){
try
{
Process p;
String command[]=new String[3];
command[0]="dmtxread ";
command[1]="-n ";
command[2]="/home/administrator/sandip/xyz.tif";
System.out.println("Command : "+command[0]+command[1]+command[2]);
p=Runtime.getRuntime().exec(command);
System.out.println(p.waitFor());
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=reader.readLine();
System.out.print("Decoded :- "+line);
}
}catch(IOException e1) {
e1.getMessage();
e1.printStackTrace();
}catch(InterruptedException e2) {
e2.getMessage();
e2.printStackTrace();
}
}
}
As when I run this java code on linux I get following exception
part of exception is as follows:
Command : dmtxread -n /home/administrator/sandip/xyz.tif
java.io.IOException: Cannot run program "dmtxread ": java.io.IOException: error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:475)
at java.lang.Runtime.exec(Runtime.java:610)
at java.lang.Runtime.exec(Runtime.java:483)
at leadertechbarcode.TwoDBarCodeReadHelper.getCodes(TwoDBarCodeReadHelper.java:53)
Some times the program hangs afterinvoking the following code line
p=Runtime.getRuntime.exec(Command)
when I copy the command printed by the code and runs it on terminal it runs properly.
Please tell me friends in this problem.
Is there any other way to invoke this command using java?
Thanks You!
The Runtime.exec(String[]) method that you are using expects the first element to be the command and the following elements to be individual arguments. As such, if there are any spaces in them they will be escaped or quoted before being passed to the underlying operating system.
In your case, command[0] contains the name of the command followed by a space. This will cause the system to search for and execute a command which has that space in its name. This can not be found.
To solve this problem you should either remove the spaces surrounding the contents of each of the elements in command, or you can concatenate them manually and pass them in as a single string to the Runtime.exec(String) method instead. Note that you also have a space trailing your "-n" argument. You will likely need to remove that one as well.
Related
I want to compile a .tex file from a Java program. I wrote the following code, and it successfully executes, but when I try to open the .pdf file generated, the OS pops a message saying that the file is completely empty (link to image).
By the way, when I run the command pdflatex tarea0.tex directly from terminal, it generates the non-empty .pdf file I want to get from the Java program.
import java.io.File;
import java.io.IOException;
class HelloWorld {
public static void main(String[] args) {
try {
ProcessBuilder pb = new ProcessBuilder("pdflatex", "tarea0.tex");
pb.directory(new File("/Users/carlosreategui/coding/java_testing/latex"));
Process p = pb.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is the link to all the files
You need to wait for the process to conclude. I'm guessing that exiting the JVM before waiting for the process to conclude causes pdflatex to receive a signal causing it to terminate abruptly.
So adding a line:
p.waitFor();
after the p.start() should have the desired effect.
I need the functionality like that of the rsync linux tool in my Java program. For that, I chose the rsync4j library.
Using their documentation, I wrote the following program:
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
import com.github.fracpete.rsync4j.RSync;
public class MainClass {
public static void main(String [] args) {
System.out.println("Started");//check
RSync rsync = new RSync()
.source("/home/arth/DataSourceFolder/a.txt")
.destination("/home/arth/DataDestinationFolder/")
.recursive(true);
// or if you prefer using commandline options:
// rsync.setOptions(new String[]{"-r", "/one/place/", "/other/place/"});
CollectingProcessOutput output = null;
try {
System.out.println("Inside try");
output = rsync.execute();
System.out.println("End of try");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(output.getStdOut());
System.out.println("Exit code: " + output.getExitCode());
if (output.getExitCode() > 0)
System.err.println(output.getStdErr());
}
}
In the snippet, in out local machine, a file a.txt is copied from one location to another. This works perfectly. The file is successfully copied when I run it and here is the output:
Started
Inside try
End of try
Exit code: 0
But my need is to sync a local directory with a directory lying at a remote host/machine. When I tried to do it using a simple rsync command from a terminal using the following command
rsync remoteUserName#23.24.25.244:/home/beth/remoteFolder/a.png /home/arth/DataSourceFolder
it works like a charm. a.png IS copied to local machine at path specified, although a password of remote machine is asked first.
But the problem when I use the above Java program to do the same operation, by replacing line # 11 and 12 by:
.source("remoteUserName#23.24.25.244:/home/beth/remoteFolder/a.png")
.destination("/home/arth/DataDestinationFolder/")
the program gets stuck after printing Started in the console. Neither an exception is thrown nor does the program proceed.
The question is that how do I fix this problem?
(old post, I know, but here it goes...) The rsync4j library does not allow interaction. In your case, the underlying rysnc binary prompts for a password in the process that the Java library created, but never receives one.
Starting with release 3.2.3-7, you can supply an instance of the sshpass wrapper to feed in the password (see this comment for an example).
My application should launch an external program to start recording the desktop.
I am using a simple program: recordmydesktop.
Launching the program works fine using ProcessBuilder.
My main issue is that I have to stop the recording. But I don't have access to the program anymore.
My first idea was to launch a terminal from java: bash did not stay open but xterm worked. First of all I would like to know why bash shell stay opened?
Then, I would like to find: How can I not use the xterm and still being able to stop the recording process? For example: send stop signal (Ctrl C) to the process.
Here is some sample code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class hh {
public static void main(String[] args) {
try {
Process process = new ProcessBuilder(new String[]{"/usr/bin/xterm" ,"recordmydesktop"}).start();
InputStream processIS = process.getInputStream();
InputStreamReader processISR = new InputStreamReader(processIS);
BufferedReader processBR = new BufferedReader(processISR);
String line;
System.out.println("Output of the record process is: ");
while ((line=processBR.readLine())!=null){
System.out.print(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Also, in this code, I am not able to get any line back. So my program does not know if the recordmydesktop is ok.
Ps: If you launch:
Process process = new ProcessBuilder(new String[]{"/usr/bin/xterm" ,"xterm"}).start();
Many xterm open instead of two. I create a loop that should not happen. This is not linked to my problem but if someone know the reason I am curious to know why.
Thanks for your help !
You can send a command to the process via the Output stream.
Process process ;
String command = "some command" ;
process.getOutputStream().writeBytes( command.getBytes() ) ;
The following method starts the cmd in Windows and it takes a parameter of the command which need to be run.
I have tested this method using the following commands: net users and it worked fine and it printed the users accounts. but if I run the dir command I get the following error:
java.io.IOEXception:
Cannot run program "dir": CreateProcess error=2, The system cannot find the file specified (in java.lang.ProcessBuilder)
Code :
private String commandOutPut;
public void startCommandLine(String s) throws IOException{
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(s); // you might need the full path
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String commandOutPut;
while ((commandOutPut = br.readLine()) != null) {
this.commandOutPut = this.commandOutPut + "\n" + commandOutPut;
}
System.out.println(this.commandOutPut);
}
Well, obviously, your method does not start cmd. How did you get this notion?
The net command is a standalone command so it runs just fine, but the dir command is not standalone, it is an internal command of cmd.exe, so you cannot run it without launching cmd.exe to execute it.
To get it to work you will have to pass not dir but cmd.exe /c dir or something like that.
Don't know if this perception can help you. But, seems that "net users" are recognized as Windows command, since "Execute" dialog can run it.
But, for some reason, the "dir" command aren't. When try to run, Windows responds that command was not found.
Additionaly, I tried run Command with inline arguments too, but the arguments are simply ignored. (sorry for bad english)
My best guess is that this is because "net" is a real executable (there is a file WINDIR\System32\net.exe"), while "dir" is a builtin command of the command interpreter - it has no executable and is directly executed within cmd.exe.
Howevever you may get around this be invoking "dir" command inside the cmd process. The syntax - as per Microsoft docs - is:
cmd /c dir
There are also some related answers on the site:
How to execute cmd commands via Java
Run cmd commands through java
You can use the following code for this
import java.io.*;
public class demo
{
public static void main(String args[])
{
try
{
Process pro=Runtime.getRuntime().exec("cmd /c dir");
pro.waitFor();
BufferedReader redr=new BufferedReader(
new InputStreamReader(pro.getInputStream())
);
String ln;
while((ln = redr.readLine()) != null)
{
System.out.println(ln);
}
}
catch(Exception e) {}
System.out.println("Done");
}
}
I tried out a simple program to execute Linux command at run time. But the following program gets compiled and runs without any error, but the text file is not getting created as intended.Is there anything wrong in this program?
import java.io.*;
class ExecuteJava
{
public static void main(String args[])
{
String historycmd = "cat ~/.bash_history >> Documents/history.txt";
try
{
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(historycmd);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Try accessing some of the functions Process provides. I'd start with exitValue. Typically a -1 indicates something went wrong while a 0 means nothing especially bad happened.
Also try InputStream and Error Stream, and read them fully. See if either has useful feedback for you.
Other than that, try what andy256 suggests in comments. Ensure the Documents directory exists in the executing directory of the program.
The append operator >> is meant to be interpreted as part of the command shell. Use
String[] historycmd =
{ "bash", "-c", "cat ~/.bash_history >> Documents/history.txt"};