Send Commands remotely from Windows to Linux through Java - java

I searched everywhere but can't find a solution that works.
I have a Linux Debian machine in my network, which is running as a Mqtt Broker. I want to write a java programm to send sub and pub commands to the broker from another computer (Windows). Is there a way to send Linux commands from a Windows Computer?
If yes, is it possible to do it through java code and recieve the proper outputs?
I tried the following:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class AA
{
public static void main(String[] args) throws Exception
{
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c",
"ssh 10.20.0.30 -l username"); // Ip of the Mqtt Broker
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line;
while (true)
{
line = r.readLine();
if (line == null)
{
break;
}
System.out.println(line);
}
}
}
The output is:
Pseudo-terminal will not be allocated because stdin is not a terminal.
I feel like this might work, if the right commands would be added.
I have heard of libraries like "Eclipse Paho", but I want to know if my solution can work.
Thanks in advance!

Your solution can work if you fallow this approach Run a command over SSH with JSch
but you mention MQTT. therefore you dont need to use ssh. you can connect to mqtt and make run commands with it. here is mqtt connection example https://www.hivemq.com/blog/how-to-get-started-with-mqtt

Try using ssh -tt in your code which might work for you.
From ssh manpage:
-t Force pseudo-tty allocation. This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful,
e.g. when implementing menu services. Multiple -t options force tty
allocation, even if ssh has no local tty.

Related

Error on executing exe from java

`I have written a below code for running exe that presently is ran through windows service. I want to call it by java program. But i am getting below error in image. I dont know how to go through installutil or debug this error. Please help me on this.
`
import java.io.*;
public class exec {
public static void main(String[] args)throws Exception {
try {
String cmd = "D://OGLWindowsService//OGL_21052014//OGL_25_Feb_2015//OGLService.exe";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(cmd);
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
}
}
You actually have the answer for your question in your first screen. windows tells you that this program is designed to be the Service and could not run from the command line. It also suggests that you use insyalutil to set your program as a service and then Windows will run it when it will need it.
Ususally service runs for some events. Most common - user connects to particular port associated with this service (for example port 80) and when such request occurs then Windows starts service progarm (IIS to answer http call) and delegate this request to this new program. Or delegeates it immediately if program is already running.
So, as you can see, Windows is in charge of the service programs. You cannot start them from command line of from another process (that's your example). You can start/stop/restart process manually in the service control window but that's still not command line or your process.

SH execution from Java GUI application don't work

I'm trying to execute a SH script from my java GUI application. I'm using jsch to connect to the machine.
I can execute commands like "ls" or "pwd". When I try to execute my SH I only get all output from it, if I execute it directly in the machine it take several time (that's what is expected) and works fine.
The script begins with
"#!/bin/bash"
and the code that call it is:
String command= "cd /opt/app/ordersync/scripts/RE-INJEC;sh ./proc_reinjec.sh"; // enter any command you need to execute
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
in = channel.getInputStream();
channel.connect();
When I execute it
I get TERM environment variable not set
I can't figure it out what is the problem. I tried to the same in php with shell_exec and I the problem (result) was the same.
This is only a guess. So consider that mostly as a (long) comment. But you are assuming your "command" will in fact be parsed by an intermediate shell, that might even be responsible to set a proper environment. But, does ChannelExec really launch a shell? Or does it instead execute directly the command?
Anyway, try that:
String command= "sh -l -c 'cd /opt/app/ordersync/scripts/RE-INJEC;sh ./proc_reinjec.sh'";
// ^^^^^^^^^^ ^
// explicit sub-shell don't forget the closing quote >-->-->----/
// '-l' is for login shell: reads /etc/profile, ... at startup
// I don't know if this is required here
But maybe in fact you are searching for ChannelShell instead?
From RFC 4254, section 6.5. Starting a Shell or a Command:
6.5. Starting a Shell or a Command
Once the session has been set up, a program is started at the
remote end. The program can be a shell, an application program, or
a subsystem with a host-independent name. Only one of these
requests can succeed per channel.
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "shell"
boolean want reply
This message will request that the user's default shell (typically
defined in /etc/passwd in UNIX systems) be started at the other end.
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string **"exec"**
boolean want reply
string command
This message will request that the server start the execution of
the given command. The 'command' string may contain a path.
Normal precautions MUST be taken to prevent the execution of
unauthorized commands.

why Eclipse throws Exception when Server program runs while not in cmd.exe

I have written a simple code of server side programming that is waiting for the response from client, this runs successfully on the cmd.exe but while executing it on the eclipse it is throwing exception, the details of exception are as follows;
Exception in thread "main" java.net.BindException: Address already in
use: JVM_Bind
this is happening in eclipse only could anyone please tell me how it is working in eclipse & how in cmd.exe
the code of server side program is :
package networking;
import java.io.*;
import java.net.*;
public class Server1 {
public static void main(String args[]) throws Exception {
ServerSocket sock = new ServerSocket(5000);
Socket s1 = sock.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
s1.getInputStream()));
String msg = br.readLine();
}
}
The socket is open when 'Server1' is started.
This can happen if:
Server1 is already running. ( you didn't kill it, seems to be the likely case...)
Another process is listening on port 5000.
The port isn't closed down quite yet, but is stuck in a "waiting" state for a while. (It can happen if a server is killed when sockets are connected.)
But! Instead of guessing, You should simply check what's going on: Download Microsoft's TCPView and have a look:
http://technet.microsoft.com/en-us/sysinternals/bb897437
(You could also use netstat -a in a cmd window.)
Some notes:
The port number
You should probably not use port 5000, as it seems to be used by uPnP - you may find that the port is always open on some machines... Check here:
http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers.
Try a 5-digit number :-)
Time_wait
Check this question about Java network server and TIME_WAIT:
The should-be-accepted answer gives the following options to reduce the window,
setSoLinger(true,0)
setReuseAddress(true)
(With the risk of losing data when killing the server as the client may not become aware of that the send failed. In the old days, data could get mixed up too, but that is no longer the case.)
This used to happen to me all the time in eclipse. Make sure nothing else with respect to your server is running. In eclipse, make sure you click the red box to terminate all instances. To double check, if in windows, go to task manager and make sure no processes related to your server are running. That should do the trick.

Rsync through java program - issues with remote connection failure

I am running rsync through my java application.(Solaris Evn)
The Java application will sync the files with remote machine. During our connection failure testing we noticed an issue running rsync through java program. The java application which is running at source side is not receiving any error message if there are any connection issues during the sync process.
Brief details about the test scenario:
We run the Java Program
The java program starts the rsync command and sync the large number of files from source to remote destination
During the sync process we run the ps -ef | grep rsync to check whether the processes are running or not at both(source and dest) side. Both side rsync processes are running.
We identify the rsync process id at target machine and kill the process with kill -9 <pid>
The java code didn't receive any error message and didn't exit. It just hung.
And also noticed that the rsync process is still running at source side and rsync process is also not printing any log message in the log file.
Note : If we run the rsync command directly (not through java program) , then everything is working fine. When we stop the rsync process at target the source process will be stopped.
When RSYNC terminated at target, the Java program and RSYNC is not detecting that the target has issues. No log files written , Java program will hang and becomes unresponsive.
Through perl its working fine. Not sure what the problem with java...!!!
I don’t have any clues to debug this issue.
Please share your thoughts and pointer to debug.
In your Java side I recommend creating two additional threads to consume the p.getInputStream() and p.getErrorStream() streams of your Process p. I think that helps rsync feel more loved and cared for.
Something like this (I'm ignoring IOExceptions for simplicity --- you'll have to deal with them!):
final Process p = Runtime.exec("rsync"); // however you do this...
Runnable consumeIn = new Runnable() {
public void run() {
InputStream in = p.getInputStream();
InputStreamReader isr = new InputStreamReader(in, "UTF-8");
BufferedReader br = new BufferedReader(isr);
String line;
while ( (line = br.readLine()) != null ) {
// Throw away the data? Or do something with it if you like!
}
}
};
Runnable consumeErr = new Runnable() {
public void run() {
InputStream in = p.getErrorStream();
// etc... (very similar to consumeIn)
}
};
new Thread(consumeIn).start();
new Thread(consumeErr).start();

Interacting with iptables via the command line

I'm trying to create a Java program that is a front-end for iptables. To accomplish this, I'm using Java's Process class and pass commands.
I'm wondering if I'm going about it correctly in general. For example, here is a selection of commands that resets iptables to its default settings, which are meant to be executed in a terminal sequentially. Am I using the Process class correctly here?
Process proc1 = Runtime.getRuntime().exec("iptables -P INPUT ACCEPT");
proc1.waitFor();
Process proc2 = Runtime.getRuntime().exec("iptables -P FORWARD ACCEPT");
proc2.waitFor();
Process proc3 = Runtime.getRuntime().exec("iptables -P OUTPUT ACCEPT");
proc3.waitFor();
Process proc4 = Runtime.getRuntime().exec("iptables -t nat -P PREROUTING ACCEPT");
proc4.waitFor();
Thanks for any direction!
You need to read the output streams, I think. Otherwise the process can block, and you'll never see anything it says.
You could also just try reading and parsing the file that iptables reads:
"/etc/sysconfig/iptables".
Executes quicker than running the iptables binary

Categories

Resources