I am programming a Java interface for the sipp command line program. My current code is:
ProcessBuilder builder = new ProcessBuilder("sipp", "-sn uac",
"127.0.0.1");
Map<String, String> environment = builder.environment();
Process javap = builder.start();
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(javap.getInputStream()));
BufferedReader reader = new BufferedReader(tempReader);
while (true){
String line = reader.readLine();
if (line == null)
break;
System.out.println(line);
}
This does not work for me thought, I have sipp environment variable set so this is not the problem. The standard output is sipp's help message. What am I doing wrong? Also I would like to know once I got sipp running is it possible to pass arguments to the processBuilder object associated with it so I can change the call rate? i.e. sipp let users change call rate by pressing + , - , * is this possible?
Try breaking up the -sn and uac parameters:
ProcessBuilder builder = new ProcessBuilder("sipp", "-sn", "uac", "127.0.0.1");
Also I would like to know once I got
sipp running is it possible to pass
arguments to the processBuilder object
associated with it so I can change the
call rate?
If sipp is expecting input from standard in, you should be able to grab an output stream (javap.getOutputStream()) to the process and write commands to it. I don't know anything about sipp to tell you whether that's how it works, though.
Related
I want to start a .jar File out of my java program using the Process Builder like this:
ProcessBuilder pb = new ProcessBuilder("java", "-Xdebug", "-DpropKey1=value", "-DpropKey2=value", "MyJar.jar");
Process p = pb.start();
I am looking for a smart way to pass a high amount of the system properties my java program is using to the ProcessBuilder. Right at this moment I am doing it like this:
StringBuilder d1 = new StringBuilder(100);
d1.append("-DpropKey1=");
d1.append(System.getProperty("propKey1"));
String d1Str = d1.toString();
StringBuilder d2 = new StringBuilder(100);
d2.append("-DpropKey2=");
d2.append(System.getProperty("propKey2"));
String d2Str = d2.toString();
ProcessBuilder pb = new ProcessBuilder("java", "-Xdebug", d1Str, d2Str, "MyJar.jar");
Process p = pb.start();
But this way doesn't seem very smart to me. It's just I have a lot of system properties I want to pass out of the java programm (more than 10). It doesn't feel right to use a StringBuilder for every system property I want to pass.
Try this:
String[] params=...
new ProcessBuilder(params).start()
Params is an array of parameters as String.
Old:
Write a method, which does the trick. As argument it could get a Map<String, String>.
The key of an entry is the parameter name, and the value of an entry is the parameter value.
The method builds the String in a loop, which is iterating over the entry set of the map.
Sorry, I read false! This will not work this way with processbuilder!
Question:
I have to call an exe file passing 2 string arguments. The call has to get executed as a different user
I referred few of the links that I got from hints. Couple of them were using powershell, few were using runas examples and so on.
But with powershell also, I am not sure if I will face the issue of "cannot be loaded because running scripts is disabled on this system".
Just because of this reason, I want to try something authentic.
Tried following approaches
Trying to do it through a call with RunAs command is making my life difficult. (called a batch file with RunAs command passing a separate pass.txt or savecred). savecred was ruled out by most people. Other one did not work as expected.
Powershell, has issues wherein, I always get a userid/password popup, even though I run through a Java file.
I also get an error in the command prompt as here below
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodExcept
ion
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.Power
Shell.Commands.NewObjectCommand
(Sample code attached below)
public class SamplePS {
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
String command = "powershell C:\\Users\\Ramu\\Project\\SampleFile.ps1";
//String cmds[] = {"C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", "\\c", "SampleFile.ps"};
System.out.println("1");
Process proc = runtime.exec(command);
InputStream is = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
System.out.println("2");
}
}
My ps1 file is as here below
$credential = New-Object System.Management.Automation.PSCredential <<domain>>\<<user id>>, <<password>>
start-process cmd.exe -arg "/k dir" -Credential $credential
What is the best way to handle this scenario?
Please suggest! I am not sure what approach to take.
Powershell or Perl or any other scripting.
Whatever it be, I have to make a call from Java file.
Please suggest!
Note: For time being, I dont mind the password being sent as a plain text.
The exe file is in Windows machine
Thanks!
Ram
For an existing Java code that I want to extend, I need to run a python code from within Java. I am using Process builder for this:
ProcessBuilder pb = new ProcessBuilder("python", "/directorypath/mypython.py");
Process p=pb.start();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
While the code runs perfectly fine from command line, in Java I get a "We need BeautifulSoup, sorry" error. As far as I understand,this means Java environment is missing some sort of libraries but then the code works perfectly from command line.
Do I need to send some environment variables? If yes, what and how?
I have 'BeautifulSoup4' installed and it is up-to-date.
Not a definitive answer but this looks to me as a problem in the environment which this process runs in; it is probably missing some environment variables which are expected by python to find your "BeautifulSoup4" extension.
A ProcessBuilder has an .environment() method returning a Map<String, String> whose keys are the environment variables and whose values are those variables' values. NOTE THAT MODIFYING THIS MAP ACTUALLY ALTERS THE ENVIRONMENT! (the one of the process you will launch, that is).
Try and print your environment and compare it with what it is when you run from the command line.
What I want to do is I want to run a process, however because this process itself relies on environment variables, directly calling it causes error within the process. For those who are wondering what this is, it's rake tool. For this reason I thought maybe it's better to use bash and using it through bash would eliminate the issue. However that doesn't seem to be the case.
Here is my code:
public static void runPB(String directory) throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder(
"/bin/bash");
processBuilder.directory(new File(directory));
Process process = processBuilder.start();
OutputStreamWriter osw = new OutputStreamWriter(process.getOutputStream());
osw.write("rake routes");
osw.close();
printStream(process.getErrorStream());
printStream(process.getInputStream());
}
public static void printStream(InputStream is) throws IOException {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
I know it is environment related issue because the error that I am getting is described here cannot load such file -- bundler/setup (LoadError)
Further I checked processBuilder.environment() returns less environment variables than entering env. I went ahead and changed the osw.write() line and tried echo $GEM_HOME there, which doesn't print anything and if I do this on my OSs bash then I get the path, I also tried other common things like echo $SHELL and it prints the shell location in both Java code and in bash.
So my questions are:
1) Why is my operating system's environment variables are different than the ProcessBuilder.environment() method?
2) Does Process class consider using environment variables that were given out by ProcessBuilder.environment()? If so then how can we add the missing ones from the operating system's level?
1) The varaibles you see in your java process are those inheritd from the process you started the java process from. I.e. If you launch it from a shell it should have the same variables as the shell had. You need to investigate which variables are actually set before launching your Java application and why the ones you expect are not set in that context.
To answer part 2, yes, the process will be launched with the environment in ProcessBuilder.environment(). You can simply add things to the map returned by ProcessBuilder.environment(), that will extend the runtime environment:
ProcessBuilder pb = new ProcessBuilder("foo");
pb.environment().put("MY_VAR", "foobar");
im using the following code to Restore PostgreSQL database using java
Runtime r = Runtime.getRuntime();
Process p;
String cmd ="D:/Program Files/PostgreSQL/9.1/bin/pg_restore.exe --host localhost --port 5432 --username postgres --dbname mytestqq --role postgres --no-password --verbose D:\sathish\rawDatabase.backup";
p = r.exec(cmd);
i have 42 tables in the rawDatabase.backup file but only one table is getting restored why the rest of the tables are not happening whats wrong in my code?
thanks in advance!!!!
It's surprising that the command you show works at all, since you're failing to quote the spaces in the command path. Try:
String[] cmd = {
"D:\\Program Files\\PostgreSQL\\9.1\\bin\\pg_restore.exe",
"--host", "localhost",
"--port", "5432",
"--username", "postgres",
"--dbname", "mytestqq",
"--role", "postgres",
"--no-password",
"--verbose",
"D:\\sathish\\rawDatabase.backup"
};
p = r.exec(cmd);
Changes:
Convert the single-string form to the much safer arguments array form of the exec call;
Double the backslashes in the rawDatabase path since your original command fails to escape backslashes, so \r is a carriage return in the string instead of the \ char followed by the r char.
Switch to doubled backslashes instead of forward slashes on the program path for consistency. This change probably doesn't matter.
Also check the return status of the process. You must use Process.waitFor() then once it has exited use Process.exitValue() to determine the result. You should examine the stderr and stdout captured by the Process object for errors and logging information.
The reason your program continues not to work is probably because:
You have old pg_restore processes hanging around holding locks; and/or
You aren't consuming stdout and stderr so pg_restore runs out of buffered pipe space and blocks writing on the output stream.
This will all be much simpler if you use ProcessBuilder instead. ProcessBuilder lets you provide file streams to write output to and generally takes care of a lot of this for you. You must still wait for the process to terminate and check its return code though.
Finally I got the solution
Runtime r = Runtime.getRuntime();
Process p;
ProcessBuilder pb;
r = Runtime.getRuntime();
pb = new ProcessBuilder(
"D:\\Program Files\\PostgreSQL\\9.1\\bin\\pg_restore.exe",
"--host=localhost",
"--port=5432",
"--username=postgres",
"--dbname=mytestqq",
"--role=postgres",
"--no-password",
"--verbose",
"D:\\sathish\\rawDatabase.backup");
pb.redirectErrorStream(true);
p = pb.start();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String ll;
while ((ll = br.readLine()) != null) {
System.out.println(ll);
}
The following code perfectly work in taking the postgres DB dump using JAVA code..Try this
List<String> cmds = new ArrayList<String>();
cmds.add("C:\\Program Files\\PostgreSQL\\9.1\\bin\\pg_dump.exe");
cmds.add("-i");
cmds.add("-h");
cmds.add("localhost");
cmds.add("-p");
cmds.add("5432");
cmds.add("-U");
cmds.add("YOUR PG USERNAME");
cmds.add("-F");
cmds.add("c");
cmds.add("-b");
cmds.add("-v");
cmds.add("-f");
cmds.add("\"E:\\pg_dump.backup\"");//Location to store db Dump backup
cmds.add("lmd");
ProcessBuilder process = new ProcessBuilder();
process.command(cmds).start();