I have two jar files named test1.jar and test2.jar.
In order to execute a function in in this jar file, I run below command in cmd.
“java getOutput argument1 argument2 argument3 argument4”
As a pre-requisite, I have set the following entries in my system environment variables to execute the java function using the above command.
1.CLASSPATH=C:\Folder\test1.jar;C:\Folder\test2.jar;C:\Program Files\Java\jre1.8.0_181\lib\plugin.jar
2.JAVA_BIN=C:\Program Files\Java\jre1.8.0_181\bin
3.JAVA_HOME=C:\Program Files\Java\jre1.8.0_181
4.PATH = C:\Program Files\Java\jre1.8.0_181\bin
The output of the above command is a string.
I have another java code. I have to capture the above string output in a variable in my java program and I am able to do this by using below java code in eclipse.
String strArgs= strArg1+" "+strArg2+" "+strArg3+" "+strArg4;
Process p=Runtime.getRuntime().exec("cmd /c java getOutput "+strArgs+"");
BufferedReader input =new BufferedReader(new
InputStreamReader(p.getInputStream()));
String strOutput = input.readLine();
if (strOutput != null) {
System.out.println(strOutput);
String strVariable = strOutput;
input.close();
}else {
System.out.println("FAIL- Output not generated");
}
In order to execute the above code on unix, I replace Line 2 with "Process p=Runtime.getRuntime().exec("usr/bin/java getOutput "+strArgs+"");" , convert the eclipse java project into a jar file named automation.jar. And I try to execute this jar file on unix using the below command .
`java -cp automation.jar Package.MainClass.'
When I run the code I get the output as null. But when I run the command on windows command prompt I get the output string.
Could you please help me on how to set the system variables in unix and perform the above operation to generate the string output.
Please let me know if any additional information required.
cmd is windows only. Unix uses a shell. But you shouldn't need either here. Just remove the cmd call.
Process p = Runtime.getRuntime().exec("java getOutput " + strArgs);
If it can't find Java, you can read the JAVA_BIN (or JAVA_HOME) from the environment.
String java_bin = System.getenv("JAVA_BIN");
Process p = Runtime.getRuntime().exec(java_bin + "/java getOutput " + strArgs);
Finally, your environment variables look like Windows path variables. Make sure they're correct for your Unix environment (Unix doesn't have a "C" drive).
Related
I am running the below query through Java on a Postgres DB using psql:
psql.exe -U <user> -w -h <host> -d <db_name> -a -f <file> 2> "<path_to_file>\psql.log"
Initially, for quite some time the java program did create the file. Then I ran into another problem, that it was not overwriting the log file. So i used file.delete() function after every time this log file got created via java.
Now, Java is not even creating the log file for some reason. If I run the above manually in command prompt, it runs absolutely fine, but not via java code. I can see this command getting run in the java log, but it does not create the log file even when i have removed the file.delete() function
I researched a lot on it but could not find any solution. Any help would be highly appreciated.
its a long code..so i will tell you the relevant part.
I am calling a function from a thread. Code is below for that function:
public static void SaveACopyfileToServer(int auditid,String filepath,String fname,String tb_name,String plpgsql_path) throws Exception
{
Map<String, String> env = System.getenv();
String plpgsql = "\""+plpgsql_path+"\" -U "+env.get("PG_USER")+" -w -h "+env.get("PG_HOST")+" -d "+env.get("PG_DB")+" -a -f "+"\""+filepath+"copy_"+tb_name+auditid+".sql\" 2> \"C:\\ER\\ETL\\logs\\psql.log\"";
System.out.println(plpgsql);
Process p = Runtime.getRuntime().exec(plpgsql);
p.getOutputStream().close();
p.waitFor();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
Calendar cal10 = Calendar.getInstance();
System.out.println("Data loaded for "+tb_name+auditid+" at "+sdf.format(cal10.getTime()));
}
After this i am calling another function which is:
public static void extracterrorreason(String fname,int auditid,String sessionid,Connection con_pg) throws FileNotFoundException, IOException, InterruptedException{
File file = new File("C:\\ER\\ETL\\logs\\psql.log");
if(file.exists())
{
System.out.println("File present");
}
else
{
System.out.println(file+" not found");
}
if (file.length()!=0){
System.out.println("Log file being read is "+file);
BufferedReader br = new BufferedReader(new FileReader(file));
String line = br.readLine();
String out_err = line.substring(line.indexOf("ERROR"));
System.out.println(out_err);
System.out.println("Error while loading the file into Database for file "+fname);
String comment = "CopyToStage','"+out_err;
Utils.updateAuditDetailTable(auditid, sessionid, -1, comment, true, con_pg,"");
br.close();
//file.delete();
}
}
The first function used to create the psql.log file, but now it does not even create it. Not sure where is the problem. Every time i run the code and from the second function,i get the printline that log file not found. The part before the redirection of the output of the cmd command works fine.
I tried process builder also..
I even tried it with Process builder
String plpgsql = "\""+plpgsql_path+"\" -U "+env.get("PG_USER")+" -w -h "+env.get("PG_HOST")+" -d "+env.get("PG_DB")+" -a -f "+"\""+filepath+"copy_"+tb_name+auditid+".sql\" 2> \"C:\\ER\\ETL\\psql_" +auditid +".log\"";
ProcessBuilder pb = new ProcessBuilder("cmd.exe",plpgsql);
Process p =pb.start();
p.getOutputStream().close();
p.waitFor();
I expect that the problem is that Runtime.getRuntime().exec(plpgsql) is splitting the command line into arguments incorrectly. Basically, exec does not understand quoting. Instead, it splits wherever it sees one or more spaces ... even if those spaces are in quotes.
The solution is to use the exec(String[]) overload, and pass each individual argument as a separate string; e.g.
.exec(new String[]{plpgsql_path,
"-U",
env.get("PG_USER"),
"-w,
"-h",
// etcetera
});
UPDATE
I didn't notice that you were using > output redirection as well1.
That doesn't work with exec either. (And the same applies to all shell syntax.) To get redirection, you need to use ProcessBuilder and one of the redirect methods.
The other alternative is to run the command in a shell. Pass the command as a string, and let the shell take care of the quote handling, substitution of environment variables, globbing, redirection ... and so on.
For example (if you were running on UNIX, Linux or MacOSX):
.exec(new String[]{"/bin/sh", "-c", plpgsql});
For Windows
.exec(new String[]{"cmd.exe", "/C", plpgsql});
Note the "/C" option in the Windows case!
1 - It serves you right for not line-breaking that ~200 character line in your source code! Check out what Java coding standards say about source line lengths ...
I am new to perl but have done some programming in java facing a problem in running the perl script present in the jar file .
I am using windows and I have written a perl script to convert one type of file to another type .
I have checked the perl script with the java program using the Runtime and I am able to run the same as required and i am getting the output converted files as well (using the cmd line)
I have created a GUI in java to get the files to convert to the target files . I am able to run the file from netbeans IDE as will .
But when I am trying to run the jar file .
I am using URL to get the URL to the perl script .
URL url = this.getClass().getResource("/com/MyProject/FileConverter/fileconverter.pl");
and Runtime for Executing the script :
String[] cmd = {"perl",path,input_file,output_file};
process = Runtime.getRuntime().exec(cmd);
Please help in resolving the issue . Basically i do need to know how we can run the perl script present in the same jar file that we are executing.
You will have to read that perl file as resource and write it somewhere on file system as File (like this) and then pass that path to your command
See Also
Extract and load DLL from JAR
I'm assuming you have your perl script file in you jar and you don't want to extract it, just execute it "from inside".
One solution is to get the "stream" of your "resource" (your perl script), and then execute "perl" writing your script in the process' standard input.
This is better explained with a piece of code:
IMPORTANT CAVEAT: the path to your script in getResourceAsStream shouldn't start with /
// Start the process "perl"
Process process = Runtime.getRuntime().exec("perl");
// get the script as an InputStream to "inject" it to perl's standard input
try (
InputStream script = ClassLoader.getSystemClassLoader()
.getResourceAsStream("com/MyProject/FileConverter/fileconverter.pl");
OutputStream output = process.getOutputStream()
) {
// This is to "inject" your input and output file,
// as there is no other easy way ot specify command line arguments
// for your script
String firstArgs = "$ARGV[0] = \"" + input_file + "\";\n" +
"$ARGV[1] = \"" + output_file + "\";\n";
output.write(firstArgs.getBytes());
// send the rest of your cript to perl
byte[] buffer = new byte[2048];
int size;
while((size = script.read(buffer)) != -1) {
output.write(buffer, 0, size);
}
output.flush();
}
// just in case... wait for perl to finish
process.waitFor();
I have written some code for executing .bat file. which contains some
commands like setting java classpath,etc..And finally there is one command
which runs a Java class file.The HelloWorld class converts some xml file and generating a new xml file in some folder. When I double click .bat file, it executes fine,
but when I try to run I am not getting any output as I was getting through
double click the .bat file. How to make a batch execute and probably it would be nice
if I could see the results through Java console.
Following is MyJava code to execute the .bat file
public void run2() {
try {
String []commands = {"cmd.exe","/C","C:/MyWork/Java/classes/run.bat"} ;
Process p = Runtime.getRuntime().exec(commands);
BufferedReader in = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
And below the some commands which has been set to .bat file
set CLASSPATH=%CLASSPATH%;C:/MyWork/Java
set CLASSPATH=%CLASSPATH%;C:/MyWork/Java/classes
java -cp test.jar;test2.jar test.HelloWorld
Tried with "/C" commad as well. It does not execute. Actually it does not give effect of double click the .bat file. Is there any other way that I can try with?
I can see the contents inside the .bat file through Eclipse console. But it does not give the desired output. Desired output means when I double click .bat file, it executes well. But through java call, I can see the contents only .
When using cmd.exe use /C-Parameter to pass command:
String []commands = {"cmd.exe","/C","C:/MyWork/Java/classes/run.bat"} ;
according to this, the Windows CMD needs the /c argument, to execute commands like this. try this:
String []commands = {"cmd.exe","/c","C:/MyWork/Java/classes/run.bat"} ;
Windows uses \ backslash for Windows and MS-DOS path delimiter. Forward slash / is accepted by Java in the java.io package and translated to be a path delimiter, but will not be directly acceptable to Windows or accepted by the cmd.exe shell.
You may also need to specify either the working directory for the batch file to be executed in, or possibly a full path to the cmd.exe command interpreter.
See: Runtime.exec (String[] cmdarray, String[] envp, File dir)
String[] commands = {"C:\\Windows\\System32\\cmd.exe", "/c",
"C:\\MyWork\\Java\\classes\\run.bat"};
File workDir = new File( "C:/MyWork");
Process process = Runtime.getRuntime().exec( commands, null, workDir);
To verify if the batch file is run at all, add a pause command to the batch file. That will keep the window open so you can verify if the batch file is launched at all, and debug this stage-by-stage.
You do not read the error output of your batch file, therefore, you'll never see any error messages printed from there or from CMD.EXE itself. In addition, the sub-program may stall and just wait for you to read the error stream.
Please see related discussions here: How to make a java program to print both out.println() and err.println() statements?
i'm trying to execute a SOX command from java, but unfortunately its returning an error everytime. Every other SOX commands are working perfectly though!!
Here is the code :
class Simple {
public static void main(String args[]) throws IOException, Exception {
Process p;
BufferedReader br;
String co = "sox speech_16.wav -p pad 0 2.5 | sox - -m speech_16.wav speech_output.wav";
p = Runtime.getRuntime().exec(co);
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
int returnCode = p.waitFor();
System.out.println("reurn code : "+returnCode);
}
}
When I'm executing the same sox command in terminal, its working fine. I really can't understand what the problem is!! Is it because of the '|' symbol??
The issue is that Runtime.exec() does not understand shell concepts such as "|". Instead try:
Runtime.getRuntime().exec("/bin/sh", "-c", co);
The problem is that exec runs a binary directly without invoking the shell. The "|" character is only recognized by the shell, not by sox. The "-c" tells the shell to run a single command, and passes the entire command as the single argument.
This is likely to be related to the environment in which the commands get executed, it could be any of the following:
The sox executable cannot be found (put the full path in the command)
The user does not have permission to run the sox command (check execute bit in file permissions)
Some environment variable needed by sox is not initialised when you run the command from Java (check sox documentation)
If speech_16.wav is an input file to sox then the file cannot be found (add full path of .wav file to command)
If sox needs to create an output file then it does not have permission to do so, either due to directory permissions, of because there is an existing file with that name which cannot be overwritten, or due to lack of space on the file-system.
How to execute a java program with the help of Runtime.getRuntime().exec().
For example we shall have the java file path as c:/java/abc.java. Please help me with the code.
Assuming that abc.java contains a main method that you want to execute:
Runtime.getRuntime().exec("javac c:\java\abc.java -d c:\java\")
Runtime.getRuntime().exec("java c:\java\abc")
Do not forget that:
you may need to read stdout/stderr of a java program
you may have to set/update environment variable and PATH before executing your java command
CreateProcess: c:\j2sdk1.4.0\bin\helloworld error=2
means Win32's CreateProcess returns a 2 as error code when it cannot find the command you specify; more specifically, when the command does not refer to an executable file on its lookup path.
Look at this SO question for a more complete "Runtime.getRuntime().exec()" code, and also to this snippet.
This code creates a shell (as in Runtime.getRuntime().exec("cmd /K")), in which you write on sdtin whatever command you want to execute.
The interest of this approach is to reuse the shell process to benefit from a previous command: it you execute a 'cd', then execute a 'dir', the latter command would display the content of the directory referenced by the cd command.
The same would be true for PATH settings, just before using javac or java.
You should use ProcessBuilder instead of Runtime. Basic usage is like:
Process process = new ProcessBuilder(command).start();
You will find more code under the link above. Also see this question.
You mean you want a Java program to run another Java program. This SO thread might be helpful, in that case.
String path1 = "f://" + File.separator+username+File.separator+progName;
Runtime runtime = Runtime.getRuntime();
String command = "javac -classpath " + path + " " + path1;
System.out.println(command);
Process process = runtime.exec(command);
InputStream error = process.getErrorStream();
Please see the excellent resource which used to be called javaalmanac.
http://www.exampledepot.com/egs/java.lang/Exec.html
try {
// Execute a command with an argument that contains a space
String[] commands = new String[]{"grep", "hello world", "/tmp/f.txt"};
commands = new String[]{"grep", "hello world", "c:\\Documents and Settings\\f.txt"};
Process child = Runtime.getRuntime().exec(commands);
} catch (IOException e) {
}