I have been trying to attempt to insert a ping command thread into my Android application, and when the server is reachable the code works great. When the server is unreachable, the process hangs and I have no idea why.
This code works in the emulator, whether the host is resolvable or not, however on an actual device, the process.waitFor never returns, and no output is published from the input or output streams.
Any ideas?
protected double executePing(String ipAddress) {
List<String> commands = new ArrayList<String>();
commands.add("/system/bin/ping");
commands.add("-c");
commands.add("5");
commands.add("-w");
commands.add("5");
commands.add("128.128.128.128");
try {
this.doCommand(commands);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return laten;
}
private void doCommand(List<String> command) throws IOException{
ProcessBuilder pb = new ProcessBuilder(command);
Process process = pb.start();
// any error message?
StreamGobbler errorGobbler = new StreamGobbler(
process.getErrorStream(), "ERROR");
// any output?
OutputStreamGobbler outputGobbler = new OutputStreamGobbler(
process.getInputStream(), "OUTPUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// read the output from the command
try {
exitVal = process.waitFor();
//Sleep for 10 secs to try to clear the buffer
Thread.sleep(6000);
//pingVal = echo.toString();
if(exitVal == 0 && !pingVal.isEmpty()){
//System.out.println("PING STATS: "+pingVal);
try{
pingVal = pingVal.substring(pingVal.lastIndexOf("rtt min/avg/max/mdev"));
pingVal = pingVal.substring(23);
pingVal = pingVal.substring(pingVal.indexOf("/")+1);
laten = Double.parseDouble(pingVal.substring(0,pingVal.indexOf("/")));
}catch (IndexOutOfBoundsException ex){
System.out.println("PING VAL: "+ pingVal);
ex.printStackTrace();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("ExitValue: " + exitVal);
}
One option would be to create a new thread to ping, and keep it open for a certain amount of time (call it a timeout). If you don't get the desired response, within the desired time, you can close the thread & try again; or, kill the process. This would give you the ability to check for specific response codes, along with the timeout.
Related
Using process builder in java but I want the program to wait while the process is finished.
I tried to use pb.wait() but it keeps on waiting. How do I wait till all the commands have finished executing?
This is a very small part of my code.
String[] commands = {All my commands go here};
String command = "cmd.exe /c " + String.join(" && ", commands);
ProcessBuilder pb = new ProcessBuilder(command.split(" "));
pb.inheritIO();
try {
pb.start();
try {
pb.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
System.out.println("Error, Could not run.");
e.printStackTrace();
}
}
The wait() method you called does not do what you expect (check javadoc for more details: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#wait(long))
You want to wait for the process you started:
Process p = pb.start();
p.waitFor();
see https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Process.html#waitFor()
Hello I'm working on a program which uses JNA 4.5.1.
I need to know whether a specific program is running or not.
Here is my problem:
hwnd = User32.INSTANCE.FindWindow
(null, "Session Dev/Prod - [32 x 80]");
if (hwnd == null) {
System.out.println("Session Dev/Prod is not running");
Process p = null;
try {
p = Runtime.getRuntime()
.exec("rundll32
url.dll,FileProtocolHandler C:
/ProgramData/Microsoft/Windows/Start
Menu/Programs/IBM Personal
Communications/TNHost");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
p.waitFor();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
else{
System.out.println("Host Already open");
User32.INSTANCE.ShowWindow(hwnd, User32.SW_MAXIMIZE );
User32.INSTANCE.SetForegroundWindow(hwnd);
}
The Problem is that the Window-Title changes depending on the monitor size.
hwnd = User32.INSTANCE.FindWindow(null, "Session Dev/Prod - [32 x 80]");
The title is always "Session Dev/Prod" + the size which changes.
I need to find the window which starts with "Session Dev/Prod".
Does anyone know how to do this. Or is there an other way to find out whether a program is running or not? I've tried to do it with Regex as parameter but the function accepts just a String.
Thank you
I had the task once to check whether a program was running or not (and if so kill it) and solved it like this:
public static void isProcessRunning(String processName) throws IOException, InterruptedException {
ProcessBuilder processBuilder = new ProcessBuilder("tasklist.exe");
Process process = processBuilder.start();
// handle errors: process.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith(processName)) {
System.out.println("Yes program is running");
break;
}
// else {
// System.out.println("No program is not running");
// }
}
}
To find out the name of your task call tasklist in the commandline and look for the name. If it is really 'Session Dev/Prod - [32 x 80]' then you can use 'Session Dev/Prod' as a string...
But note that this is a windows solution. For linux you have to use something like ps -ef
If someone have an actual solution to this problem i would much appreciate it. So far all implementation that I have used close the session as soon as one of the channel is "connected" what ever that means. Like most i need to be able to script ssh interaction meaning that i need the result of my operation with a still alive channel I'm not looking for a command with "cmd1;cmd2;cmd3" type ..
The best example I can think of is if you were trying to browse trough a file system.
If each command is a new session you would be going going no where since at each new session you go back to square one.
In command line the ssh session remain open when you type an operation why all java implementation differ so much from this approach is beyond me. My next step if i cant find an answer is actually to use command shell from java and interacting from there instead of using java ssh libraries..
public void connect() {
Session session;
try {
session = createConnectedSession();
java.util.logging.Logger.getLogger("test").log(Level.INFO,"isConnected "+session.isConnected());
ByteArrayOutputStream output = new ByteArrayOutputStream();
Channel channel = session.openChannel("shell");
channel.setOutputStream(output);
PrintStream ps = new PrintStream(channel.getOutputStream(), true);
// InputStream is = new InputStream(channel.getInputStream());
channel.connect();
sleep();
java.util.logging.Logger.getLogger("test").log(Level.INFO,"isConnected "+session.isConnected());
Stack<String> mstack = getCommandStack();
//readChannel(channel);
while (!mstack.isEmpty()) {
String cmd = mstack.pop();
java.util.logging.Logger.getLogger("test").log(Level.INFO,"sending command "+cmd);
ps.println(cmd);
sleep();
System.out.println(output.toString());
java.util.logging.Logger.getLogger("test").log(Level.INFO,"command result"+output.toString());
sleep();
// System.out.println(output.toString());
ps.flush();
}
channel.disconnect();
session.disconnect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have been researching how to run a terminal command in java. I am doing this to make a program I can use to ssh into another pc (just as a project). How could I keep continuing putting commands in this terminal? If I run this I get a message to put in my password and if I do so it will print out what the messages the terminal spits out at the :
while((line = in.readLine()) != null){
System.out.println(line + "\n");
}
line, but a few seconds after that my program will stop working.
I currently have a GUI that is just a button and if I press the button it will run this code. Could someone help me to fix the issue of it stopping and give me information on how I could continue to put commands into the terminal? Thanks.
Process p = null;
String[] command = {"/bin/sh", "-c", "ssh 192.168.2.100"};
ProcessBuilder pb = new ProcessBuilder(command);
String line = null;
try {
term = pb.start();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
InputStream is = p.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
try {
while((line = in.readLine()) != null){
System.out.println(line + "\n");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You can not pass the argument to live JVM, But there is way in which you can modify the some of the parameters which done using JMX, with this you can connect to live JVM and send the parameters. which will be taken the effect immediately.
Hope that helps
i wanted to read the output-stream of a c-Application in my Java program. iremoted (available here: Link) is a C-Application that puts out seperate lines like "0x19 pressed" if a button on my Apple Remote is pressed. If i start the iremoted program everything is doing well and these separate lines are shown on my screen everytime I pressed a button.
Now I wanted to read the output-stream of the c-application in my Java application to process inputs of the Apple Remote in Java projects.
Unfortunately i don't know why no input is regocnized?
I tried it with a simple HelloWorld.c program and my program responded as intended in this case (prints out HelloWorld).
Why doensn't it work with the iremoted program?
public class RemoteListener {
public void listen(String command) throws IOException {
String line;
Process process = null;
try {
process = Runtime.getRuntime().exec(command);
} catch (Exception e) {
System.err.println("Could not execute program. Shut down now.");
System.exit(-1);
}
Reader inStreamReader = new InputStreamReader(process.getInputStream());
BufferedReader in = new BufferedReader(inStreamReader);
System.out.println("Stream started");
while((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
System.out.println("Stream Closed");
}
public static void main(String args[]) {
RemoteListener r = new RemoteListener();
try {
r.listen("./iremoted"); /* not working... why?*/
// r.listen("./HelloWorld"); /* working fine */
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
stdout is buffered and it's not automatically flushed if you are not writing to screen. Add:
fflush(stdout);
after:
printf("%#lx %s\n", (UInt32)event.elementCookie,
(event.value == 0) ? "depressed" : "pressed");
iremoted is likely writing to stderr if a hello world program works. You would want the error stream in that case. I'm not sure how this works for your hello world case - I think you're doing the wrong thing here:
new InputStreamReader(process.getInputStream());
should be
new InputStreamReader(process.getOutputStream());
or
new InputStreamReader(process.getErrorStream());