I am trying to spin up zookeeper and kafka servers from my java code. We usually execute the batch files manually, I am trying to automate but the server never starts.
I have tried running other .bat files using the same code and they run like a charm but the zookeeper and kafka-server ones never execute successfully nor do they throw any error
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c",
"C:/kafka_2.11-2.1.0/kafka_2.11-2.1.0/bin/windows/zookeeper-server-start.bat",
"C:/kafka_2.11-2.1.0/kafka_2.11-2.1.0/config/zookeeper.properties"});
I want the zookeeper server to get started and remain started whereas it doesn't. Please help where am I going wrong, is this even possible?
Below program worked for me, it will print all logs to console and will wait for the process to terminate:
import java.io.*;
public class ExecuteProg {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c",
"E:/Softwares/kafka_2.11-2.0.0/bin/windows/zookeeper-server-start.bat",
"E:/Softwares/kafka_2.11-2.0.0/config/zookeeper.properties"});
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();
}
}
}
I exactly don't know why but adding the "start" flag made it work for me. Now I am able to run both the zookeeper and kafka servers from within the code. The code I am using is as follows,
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "start",
"C:/kafka_2.11-2.1.0/kafka_2.11-2.1.0/bin/windows/zookeeper-server-start.bat",
"C:/kafka_2.11-2.1.0/kafka_2.11-2.1.0/config/zookeeper.properties"});
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "start",
"C:/kafka_2.11-2.1.0/kafka_2.11-2.1.0/bin/windows/kafka-server-start.bat",
"C:/kafka_2.11-2.1.0/kafka_2.11-2.1.0/config/server.properties"});
Related
I am trying to connect to a windows machine from a linux machine via openSSH and run some powershell commands on windows box. I cannot install powershell on linux box due to some restrictions.
Manually launching openSSH from linux and then running commands is working perfectly.
I am trying to do same thing in Java, but the problem is that I am not seeing output of powershell commands ran.
Below is the code to reproduce the same:
public class Example {
public static class Writers exte ds Thread {
Process process;
Writers(Process p) {
process =p;
}
public void run() {
try {
OutputStreamWriter writer= new OutputStreamWriter(process.getOutputStream);
String command = "expect -c 'spawn ssh user#host ; expect \"password\" ; send \"passcode\\r\"; interact' \n";
writer.write(command);
writer.write("echo \"hello123\");
writer.flush();
} catch (Exception e) {}
}
public static void main(String[] args) throws Exception {
ProcessBuilder builder = new ProcessBuilder("bash");
builder.redirectErrorStream(true);
Process process = builder.start();
Example.Writers writers = new Example.Writers(process);
writers.start();
BufferedReader stdout = new BufferedReader( new InputStreamReader(process.getInputStream()));
String s = null;
while((s= stdout.readLine()) != null) {
System.out.println(s);
}
}
}
OUTPUT:
I see only Windows powershell startup logo and nothing after that.
Tell me why this hello123 not getting printed.
Or, why the powershell output stream not getting redirected to output stream of linux machine ?
manually opening interactive ssh shell and running powershell commands run perfectly, but not via code.
interactive modes don't work nice with scripts and codes and are not recommended. It's better to use some existing ssh framework like jsch to connect, which are available as open source maven dependencies.
I have a Hadoop YARN cluster set up on some machines at my university (all machines running Linux Fedora 25). When running a mapreduce job in YARN, I am unable to receive the output from a call I make to a separate program. Interestingly, if I run my job locally (configured in mapred-site.xml), my method for calling the program and receiving its output works just fine. Below is my executeShellCommand class, which is instantiated and used in my first map task.
public class ExecuteShellCommand {
public String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
String [] args = command.split(" ");
String cmd = args[0];
ProcessBuilder pb = new ProcessBuilder().command(cmd, args[1], args[2], args[3], args[4], args[5], args[6], args[7]).directory(new File("path to executable"));
p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
p.waitFor();
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
return output.toString();
}
}
Things I have made sure to check:
1) Permissions are appropriately set for all files/directories needed
2) Map tasks are run as current user (me), so no issues with illegal access
3) I am not receiving a file not found exception, so the path to the program I'm calling is correct
4) Checked the input/output stream for Process p (input stream set as java.lang.UNIXProcess$ProcessPipeInputStream#1000e80, output stream is null)
5) Instead of calling the program I need to use, I have tried a simple "echo" command, and could not receive that output either.
6) I have also tried using
p = Runtime.getRuntime().exec("myCommand")
but the results are the same (no output received)
As I already mentioned, when I run a job locally, my executeCommand method functions perfectly, and returns the output from the program I call. Only in YARN do the issues occur. I have a feeling that the problem caused by either not reading from the correct buffer, or the command issued to ProcessBuilder is never actually executed. I am quite stumped as to how to debug what is going on here, and any tips would be greatly appreciated!
After hours of trying all sorts of solutions, I figured out how to get the error stream from the process spawned with ProcessBuilder. Turns out when I set the working directory for the process, I forgot to update the path to one of the arguments I was passing it. D'oh!!!
I already create the .sh file, and the inside is:
sudo iptables --flush
sudo iptables -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j DROP
It works normally when I run it on the terminal, but when I use processbuilder, it didn't do anything. No error, but didn't happen anything, this is the code on my java:
Process pb = new ProcessBuilder("/bin/bash","/my/file.sh").start();
I already looking for the answer, but I still failed to run the .sh file, even I do the same thing with people that already done it.
Sorry if this is a bad question, thank you.
Are you sure that the bash is not run? Do you checked the Process object returned by the startmethod? You can get the output value, the output stream, etc. from this objects.
Check your streams and exitvalue for errors... sudo is probably the problem here.
Not necessarily the best code but it gets the job done. Executes a process, takes the process.streams and prints them to System.out. Might helpt to find out what the issue actually is atlest.
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
final Process proc = pb.start();
final StringBuilder builder = new StringBuilder("Process output");
final Thread logThread = new Thread() {
#Override
public void run() {
InputStream is = proc.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
try {
String line;
do {
line = reader.readLine();
builder.append("");
builder.append(line == null ? "" : line);
builder.append("<br/>");
} while(line != null);
} catch (IOException e) {
builder.append("Exception! ").append(e.getMessage());
} finally {
try {
reader.close();
} catch (IOException e) {
builder.append("Exception! ").append(e.getMessage());
}
}
}
};
logThread.start();
int retVal = proc.waitFor();
System.out.println(builder.toString());
From Java API Runtime : http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
// Java runtime
Runtime runtime = Runtime.getRuntime();
// Command
String[] command = {"/bin/bash", "/my/file.sh"};
// Process
Process process = runtime.exec(command);
Also you should be careful with sudo commands that may ask for root password.
I was developing a project in Java to scan the File System and this involves executing dos commands in java with administrative privilege.
I already wrote the program to execute simple dos commands in Java.
public class doscmd {
public static void main(String args[]) {
try {
Process p = Runtime.getRuntime().exec("cmd /C dir");
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
} catch (IOException e1) {
} catch (InterruptedException e2) {
}
System.out.println("Done");
}
}
But as you can see this does not allow to execute elevated commands.
I am developing the project in Netbeans IDE and i was hoping if any of you folks could tell me if there is any code in java to get admin privilege instead of converting the file to .exe and then clicking run as administrator.
Your JVM needs to be running with admin-privileges in order to start a process with admin-privileges.
Build your code and run it as an administrator - every process spawned by your class will have administrator privileges as well.
try this code, it works for me:
String command = "cmd /c start cmd.exe";
Process child = Runtime.getRuntime().exec(command);
OutputStream output = child.getOutputStream();
output .write("cd C:/ /r/n".getBytes());
output .flush();
output .write("DIR /r/n".getBytes());
output .close();
I am trying to execute a netsh command in Java. I wanna get available networks. I can run this code on cmd :
"netsh wlan show network mode=Bssid > D:\\output.txt"
It works. When I try run this code in Java, it doesn't work.
Process networks= Runtime.getRuntime().exec("netsh wlan show network mode=Bssid > D:\\output.txt");
How can fix do that?
There is an exec-overload, where you may pass arguments as String-array.
Actually netsh.exe cannot deal with this.
Solution is to execute netsh inside a command line interpreter, like
Runtime.getRuntime().exec(new String[] {"cmd.exe", "/Cnetsh wlan show network mode=Bssid > D:\\output.txt"});
Anyway the command line interpreter is the only way to handle the output filter ´>´
Else, you might omit writing to a file and access the output immediately as String list
BufferedReader input = new BufferedReader(new InputStreamReader(networks.getInputStream()));
List<String> res = new ArrayList<String>();
String line;
try
{
while ((line = input.readLine()) != null)
{
res.add(line);
}
}
catch (Exception x)
{
x.printStackTrace();
}
You would do this anyway to be synchronous with the called process.