In java application I have my properties file which has key/pair values like
usa.national.bank=Bank of America
etc.
Now let's say I deploy my app in a unix box, where I already have variables declared like:
export US_NAT_BANK=Bank of America
SO my app is supposed to run in this unix box and at run time at some point, it will read this value.
So tried declaring my properties file like this:
usa.national.bank=$US_NAT_BANK
but it is not able to read the value defined in variable i.e. "Bank of America", instead it reads the literal value i.e. "$US_NAT_BANK"
AM I doing something wrong or is it not possible to use unix variables in property files?
Java has API to interact with System commands using ProcessBuilder.
You can use following solution to read UNIX properties using java :
ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash", "-c", "echo $US_NAT_BANK");
final Process process = processBuilder.start();
try (InputStream is = process.getInputStream()) {
byte[] result = is.readAllBytes();
System.out.println(new String(result, UTF_8));
}
Using ProcessBuilder you can execute any UNIX supported commands and get same results as you get in console/terminal.
You can more details : ProcessBuilder JavaDoc
Related
I want to execute a batch file code from java button click. Also I don't want any command prompt window to be shown all from java code.
I have a code :-
C:\xyz-3.1.1\bin>dita --input=C:/Users/india/Desktop/mobile-phone/m
obilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Use
rs/india/Desktop/dofhdif.txt
So I want above code to be run from batch command with C:\xyz-3.1.1\bin> as the parent directory.
Also I want to update --input file path whenever I will choose new file from JFileChooser.
I did this from the java code on button click transform:-
ProcessBuilder pb=new ProcessBuilder("dita --input=C:/Users/india/Desktop/mobile-phone/mobilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Users/india/Desktop/dofhdif.txt");
pb.redirectErrorStream(true);
Process process=pb.start();
and getting IOException error.
I get stuck over here for long time , where am I going wrong.
EDIT :- error
java.io.IOException: Cannot run program "dita --input=C:/Users/india/Desktop/mobile-phone/m
obilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Use
rs/india/Desktop/dofhdif.txt": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
As the Error mentioned, it cannot locate the command because the whole string will be treated as the command by ProcessBuilder.
Try to use Runtime.getRuntime().exec directly, but you have to ensure the command dita can be found.
Process process = Runtime.getRuntime().exec("C:\xyz-3.1.1\bin>dita --input=C:/Users/india/Desktop/mobile-phone/mobilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Users/india/Desktop/dofhdif.txt");
process.waitFor();
int exitCode = process.exitValue();
System.out.println(IoHelper.output(process.getInputStream())); // handle the output;
Before JDK 5.0, the only way to start a process and execute it, was to use the exec() method of the java.lang.Runtime class after which ProcessBuilder can be used to help create operating system processes.
The major improvement being that, it also acts as a holder for all those attributes that influence the process. And this is how it should be used:
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
P.S. Actually Runtime.getRuntime().exec can also be used with String... as:
Runtime.getRuntime().exec(new String[]{"curl", "-v", "--cookie", tokenString, urlString});
My personal preference:
If you have to configure the environment for the command: to control the working directory or environment variables and also you want to execute the commands several times, you'd better use it since the ProcessBuilder will hold the settings and what you need to do is just processBuilder.start() to create another process with the same settings;
If you want to execute a whole long string command as you mentioned, you'd better just use Runtime.getRuntime().exec since you can just execute it right there without any bothering of the parameter format.
Try this:
String inputFile = ...;
String outputFile = ...;
String logFile = ...;
ProcessBuilder pb = new ProcessBuilder(
"dita",
"--input=" + inputFile,
"--format=pdf",
"--output=" + outputFile,
"--logfile=" + logFile)
.directory(new File("C:\\xyz-3.1.1\\bin"))
//.inheritIO();
.redirectErrorStream(true);
Process process = pb.start();
This shows the following points:
The command is separated from the arguments
The argument values can be determined at runtime
The command's default directory (C:\xyz-3.1.1\bin) is set before starting the process
Consider using inheritIO() instead of redirectErrorStream() if you want the process's output to appear as part of your Java application's output.
I need to run executable progam (.exe) in java. This program have two different operating modes: GUI and Command line. The syntax to launch the program from the command line is as follows :
C:\Users\Ermanno\Desktop\ "programFolder"\"program.exe" /stext output.txt
in this way the program store the outoput in the file "output.txt".
I tired it:
Process p = new ProcessBuilder("C:\\Users\\Ermanno\\Desktop\\programFolder\\program.exe" ,"/stext a.txt").start();
does not create the output file.
I also tired to use a file batch that contains the command and run it to java but the result is the same.
You need to pass each argument in a single string:
... program.exe", "/stext", "a.txt")...
Also make sure that you start a background thread which reads the output of the child process. If there is a problem, then the child will print an error message to it's standard output and if you don't actively read it, then this output will be lost.
For this, loop over the streams p.getInputStream() and p.getErrorStream().
The latter is especially important since you say "I also tired to use a file batch". Java doesn't do anything different than a batch script. If you can't run the command from batch, it won't work from Java, either.
My experience was horrible with using the JDK ProcessBuilder and Runtime.getRuntime().exec. I then moved to Apache commons-exec. Here is an example:
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
I solved using file bath. This file contains the command.
String [] _s = {"cmd.exe", "/c", "start", "file.bat"};
Process pr = Runtime.getRuntime().exec(_s);
I am trying to call a python script from a java/tomcat6 webapp. I am currently using the following code:
Process p = Runtime.getRuntime().exec("python <file.py>");
InputStream in = p.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader b = new BufferedReader(isr);
logger.info("PYTHON OUTPUT");
String line = null;
while ( (line = b.readLine()) != null){
logger.info(line);
}
p.waitFor();
logger.info("COMPLETE PYTHON OUTPUT");
logger.info("EXIT VALUE: "+p.exitValue());
I can't really see any output in the catalinia.out file from the python script and using an adapter library like jython is not possible as the script relies on several machine learning libraries that need python's Numpy module to work.
Help?
The explanation is probably one (or more) of following:
The command is failing and writing error messages to its "stderr" fd ... which you are not looking at.
The command is failing to launch because the command name is incorrect; e.g. it can't be found on $PATH.
The command is trying to read from its stdin fd ... but you haven't provided any input (yet).
It could be a problem with command-line splitting; e.g if you are using pathnames with embedded spaces, or other things that would normally be handled by the shell.
Also, since this is python, this could be a problem with python-specific environment variables, the current directory and/or the effective user that is executing the command.
How to proceed:
Determine if the python command is actually starting. For instance. "hack" the "" to write something to a temporary file on startup.
Change to using ProcessBuilder to create the Process object. This will give you more control over the streams and how they are handled.
Find out what is going to the child processes "stderr". (ProcessBuilder allows you to redirect it to "stdout" ...)
So I have a client and a server Java program. The client uses Java processbuilder to execute the script but my problem is that the user inputs information that needs to be passed to the bash script. So, essentially, I need to know how to send three different strings to three different variables that are being read by the bash script. This script is copying a file so I would rather not make a txt file with java and have the script read the file. I would also like a way for this to be able to run on OS X and Windows so improvements are welcome. I am using Java 7 on Ubuntu currently.
Here is a snippet of what I am trying to do:
.java
Scanner bob = new Scanner(System.in);
String workingDirectory = new String(System.getProperty("user.dir"));
File tempDir = new File(workingDirectory);
String script = new String(workingDirectory + "/copyjava.sh");
System.out.print("Designate the location of the file: ");
String loc = bob.next();
System.out.print("Type the name of the file w/ extension: ");
String name = bob.next();
System.out.print("What is the location of THIS file? "); //I know there is a way to do this automagically but I can't remember how...
String wkspace = bob.next();
ProcessBuilder pb = new ProcessBuilder( script, loc, name, wkspace);
pb.start();
File myFile = new File (name);
Script:
read loc
read name
read wkspace
cd $LOC
cp $name $wkspace
There is a problem with your shell script. The read command reads from stdin, but you are passing the input as arguments. You are also changing the case of the loc variable. Variables in the shell are case sensitive. Change your script to the following:
#!/bin/sh
loc=$1
name=$2
wkspace=$3
cd "$loc" || { printf 'failed to cd to %s\n' "$loc" ; exit 1; }
cp "$name" "$wkspace" || { printf 'failed to copy %s\n' "$name" ; exit 1; }
On a side note, you shouldn't need to call an external script written in a different language just to copy a file. You should implement this in java. Implementing this in java will also give your code the platform independence you desire.
You are passing your args on the command line but reading from stdin in your script. How about changing your script to:
cd $1
cp $2 $3
I don't see any client/server interaction but let's focus on what's really important: Your are passing the parameters to the script but your script is trying to read them from the standard input.
To fix your problem modify your script as follows:
#!/bin/sh
LOC=$1
name=$2
wkspace=$3
cd $LOC
cp $name $wkspace
Take a look at the documentation for more details.
But are not doing anything that would really need a system-specific script file. The best way to copy a file is using the own mechanism that Java provides and then you don't need to worry of the underlying operating system.
If you keep on using the script then you'll need another one for Windows systems and then decide which script you should run based on the value of the os.name system property.
I have an exe file which takes a file name as input.
When I execute it as a command like:
xyz.exe c:\input.txt c:\ouput.txt
It all works as expected.
But how to execute this is java?
This is the one i used and am not getting the ouput in the files:
String[] str = {"c:/input.txt","c:/output.txt"};
Process p = rt.exec("c:/xyz.exe",str);
You're using the method:
public Process exec(String command,
String[] envp)
where envp is a (quote) "array of strings, each element of which has environment variable settings in the format name=value, or null if the subprocess should inherit the environment of the current process."
Try this instead:
String[] command = {"c:/xyz.exe", "c:/input.txt", "c:/output.txt"};
Process p = Runtime.getRuntime().exec(command);
// ...
Also read this article that explains the pitfalls of Runtime.exec(...): http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
Use Runtime.exec or Processbuilder API
I believe this should answer your question http://www.daniweb.com/software-development/java/threads/133710