Sending commands to server via JSch shell channel - java

I can't figure it out how I can send commands via JSch shell channel.
I do this, but it doesn't work:
JSch shell = new JSch();
String command = "cd home/s/src";
Session session = shell.getSession(username, host, port);
MyUserInfo ui = new MyUserInfo();
ui.setPassword(password);
session.setUserInfo(ui);
session.connect();
channel = session.openChannel("shell");
fromServer = new BufferedReader(new InputStreamReader(channel.getInputStream()));
toServer = channel.getOutputStream();
channel.connect();
toServer.write((command + "\r\n").getBytes());
toServer.flush();
and then I read input like this:
StringBuilder builder = new StringBuilder();
int count = 0;
String line = "";
while(line != null) {
line = fromServer.readLine();
builder.append(line).append("\n");
if (line.endsWith(".") || line.endsWith(">")){
break;
}
}
String result = builder.toString();
ConsoleOut.println(result);

Try this:
JSch jsch = new JSch();
try
{
Session session = jsch.getSession("root", "192.168.0.1", 22);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
String command = "lsof -i :80";
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
while (true)
{
while (in.available() > 0)
{
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed())
{
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try
{
Thread.sleep(1000);
}
catch (Exception ee)
{
}
}
channel.disconnect();
session.disconnect();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}

If it hangs at readLine() that means either your "while" is never ending (might be unlikely considering your code), or, readLine() is waiting for its source, namely the IOstream blocks the thread cause available()!=true.
I can't quite troubleshoot your code without seeing your debug info. But as an advice, have you tried PipedIntputStream? The idea is to pipe your console input to "your" output so that you can "write" it. To implement this, you need to initialize the in/out-put.
InputStream in = new PipedInputStream();
PipedOutputStream pin = new PipedOutputStream((PipedInputStream) in);
/**...*/
channel.setInputStream(in);
channel.connect();
/** ...*/
pin.write(myScript.getBytes());
The same goes to your question, how to read console output.
PipedInputStream pout = new PipedInputStream((PipedOutputStream) out);
/**
* ...
*/
BufferedReader consoleOutput = new BufferedReader(new InputStreamReader(pout));
consoleOutput.readLine();
And again, if you are not sure how many lines to read and thus want to use "while", make sure you do something inside while to prevent 1) busy-waiting 2) ending-condition. Example:
while(!end)
{
consoleOutput.mark(32);
if (consoleOutput.read()==0x03) end = true;//End of Text
else
{
consoleOutput.reset();
consoleOutput.readLine();
end = false;
}
}

Following was a quickly written code for my assignment. Not a well done program.
But serves its purpose.
Connects via SSH (using Jsch) to a server (using a Private Key File - mykey.pem)
Creates a shell script (to mount a volume and mkfs)
Runs on the remote machine
All the while you can see the output on your stdout
The code follows:
public class connectSSH {
public void connect(String dnsName, String privKey) throws IOException {
JSch jSch = new JSch();
try {
//Authenticate through Private Key File
jSch.addIdentity(privKey);
//Give the user and dnsName
Session session = jSch.getSession("root", dnsName, 22);
//Required if not a trusted host
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
System.out.println("Connecting SSH to " + dnsName + " - Please wait for few minutes... ");
session.connect();
//Open a shell
Channel channel=session.openChannel("shell");
channel.setOutputStream(System.out);
//Create a Shell Script
File shellScript = createShellScript();
//Convert the shell script to byte stream
FileInputStream fin = new FileInputStream(shellScript);
byte fileContent[] = new byte[(int)shellScript.length()];
fin.read(fileContent);
InputStream in = new ByteArrayInputStream(fileContent);
//Set the shell script to the channel as input stream
channel.setInputStream(in);
//Connect and have fun!
channel.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public File createShellScript() {
String filename = "shellscript.sh";
File fstream = new File(filename);
try{
// Create file
PrintStream out = new PrintStream(new FileOutputStream(fstream));
out.println("#!/bin/bash");
out.println("echo \"hi\" > /tmp/test.info");
out.println("echo \"n\" > /tmp/fdisk.in");
out.println("echo \"p\" >> /tmp/fdisk.in");
out.println("echo \"1\" >> /tmp/fdisk.in");
out.println("echo >> /tmp/fdisk.in");
out.println("echo >> /tmp/fdisk.in");
out.println("echo \"w\" >> /tmp/fdisk.in");
out.println("/sbin/fdisk /dev/sdf < /tmp/fdisk.in");
out.println("mkfs.ext3 /dev/sdf1");
out.println("mkdir /usr/myebs");
out.println("mount /dev/sdf1 /usr/myebs");
out.println("partprobe /dev/sdf1");
out.println("echo \"Success\"");
//Close the output stream
out.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
return fstream;
}
public static void main(String[] args) {
connectSSH ssh = new connectSSH();
String privKey = "/Users/neo/Desktop/mykey.pem";
try {
ssh.connect("yourexampleserver.com", privKey);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

private void executeRemoteCommandAsSudo(String sudoAs, String password,
String command, int delayInSeconds)
{
logger.info("executeRemoteCommandAsSudo started....");
logger.info("sudoAs=" + sudoAs);
logger.info("command=" + command);
logger.info("delayInSeconds=" + delayInSeconds);
Session session = null;
Channel channel = null;
try {
session = getSession();
channel = session.openChannel("exec");
String sudoCommand = "sudo su - " + sudoAs;
((ChannelExec) channel).setCommand(sudoCommand);
((ChannelExec) channel).setPty(true);
channel.connect();
InputStream inputStream = channel.getInputStream();
OutputStream out = channel.getOutputStream();
((ChannelExec) channel).setErrStream(System.err);
out.write((password + "\n").getBytes());
out.flush();
Thread.sleep(1000);
out.write((command + "\n").getBytes());
out.flush();
Thread.sleep(1000 * delayInSeconds);
out.write(("logout" + "\n").getBytes());
out.flush();
Thread.sleep(1000);
logInfo(channel, inputStream);
out.write(("exit" + "\n").getBytes());
out.flush();
out.close();
Thread.sleep(1000);
} catch (Exception ex) {
logger.error(ex.getMessage());
} finally {
session.disconnect();
channel.disconnect();
}
logger.info("executeRemoteCommandAsSudo completed....");
}
private void logInfo(Channel channel, InputStream in)
{
try {
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
logger.info(new String(tmp, 0, i));
}
if (channel.isClosed()) {
logger.info("exit-status: " + channel.getExitStatus());
break;
}
}
} catch (Exception ex) {
logger.error(ex);
}
}
private Session getSession() throws JSchException
{
JSch jsch = new JSch();
logger.info("ftpUser=" + ftpUser);
logger.info("ftpHost=" + ftpHost);
Session session = jsch.getSession(ftpUser, ftpHost, 22);
session.setPassword(ftpPassword);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
return session;
}

With piped input and output streams seems interesting:
JSch jsch = new JSch();
jsch.addIdentity("/home/audrius/.ssh/blablabla", "blablablabla");
String user = "audrius";
String host = "ultrastudio.org";
Session session = jsch.getSession(user, host, 439);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
Channel channel = session.openChannel("shell");
PipedInputStream pip = new PipedInputStream(40);
channel.setInputStream(pip);
PipedOutputStream pop = new PipedOutputStream(pip);
PrintStream print = new PrintStream(pop);
channel.setOutputStream(System.out);
print.println("ls");

I realize that this is an old thread, but I have struggled with a similar problem today.
This is my solution.
public class ChannelConsole {
// ================================================
// static fields
// ================================================
// ================================================
// instance fields
// ================================================
private Session session;
// ================================================
// constructors
// ================================================
public ChannelConsole(Session session) {
this.session = session;
}
// ================================================
// getters and setters
// ================================================
// ================================================
// public methods
// ================================================
public String execute(String command) throws JSchException {
command = command.trim() + "\n";
ChannelExec channel = (ChannelExec) this.session.openChannel("exec");
channel.setCommand(command);
ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
channel.setOutputStream(responseStream);
channel.connect();
try {
awaitChannelClosure(channel);
} catch (InterruptedException e) {
// no one cares
}
String result = responseStream.toString();
closeQuietly(responseStream);
return result;
}
// ================================================
// private methods
// ================================================
private void awaitChannelClosure(ChannelExec channel) throws InterruptedException {
while (channel.isConnected()) {
Thread.sleep(100);
}
}
private static void closeQuietly(Closeable closeable) {
if (closeable == null) {
return;
}
try {
closeable.close();
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
}
Using this class you can just do something like :
shell = new ChannelConsole(this.session);
String result = shell.execute("quota -v; echo; echo \"Disk storage information:\"; df -hk")

try this
Channel channel=session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
ps.println("mkdir folder");
ps.println("dir");
//give commands to be executed inside println.and can have any no of commands sent.
ps.close();
InputStream in=channel.getInputStream();
byte[] bt=new byte[1024];
while(true)
{
while(in.available()>0)
{
int i=in.read(bt, 0, 1024);
if(i<0)
break;
String str=new String(bt, 0, i);
//displays the output of the command executed.
System.out.print(str);
}
if(channel.isClosed())
{
break;
}
Thread.sleep(1000);
channel.disconnect();
session.disconnect();
}

Usage:
String remoteCommandOutput = exec("ssh://user:pass#host/work/dir/path", "ls -t | head -n1");
String remoteShellOutput = shell("ssh://user:pass#host/work/dir/path", "ls")
shell("ssh://user:pass#host/work/dir/path", "ls", System.out)
shell("ssh://user:pass#host", System.in, System.out);
Implementation

When using JSch you have to use an InputStream for communication from your SSH client to the server and an OutputStream back from the server to the client. That is probably not very intuitive.
The following examples use piped streams to provide a more flexible API.
Create a JSch session ...
Session session = new JSch().getSession("user", "localhost", port);
session.setPassword("secret");
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
If you want to send multiple commands to a shell you should use the ChannelShell as follows:
ChannelShell channel = (ChannelShell) session.openChannel("shell");
PipedInputStream pis = new PipedInputStream();
channel.setInputStream(pis);
PipedOutputStream pos = new PipedOutputStream();
channel.setOutputStream(pos);
channel.connect();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new PipedOutputStream(pis)));
writer.write("echo Hello World\n");
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(new PipedInputStream(pos)));
String line = reader.readLine(); // blocking IO
assertEquals("Hello World", line);
With the help of an ByteArrayOutputStream you can also communicate in a non-blocking way:
ChannelShell channel = (ChannelShell) session.openChannel("shell");
channel.setInputStream(new ByteArrayInputStream("echo Hello World\n".getBytes()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
channel.setOutputStream(baos);
channel.connect();
sleep(1000); // needed because of non-blocking IO
String line = baos.toString();
assertEquals("Hello World\n", line);
If you just want to send one command the ChannelExec is enough. As you can see the output stream works in the same way like before:
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("echo Hello World");
PipedOutputStream pos = new PipedOutputStream();
channel.setOutputStream(pos);
channel.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(new PipedInputStream(pos)));
String line = reader.readLine(); // blocking IO
assertEquals("Hello World", line);

try this code :
JSch jsch=new JSch();
System.out.println("Getting session");
Session session=jsch.getSession("root","10.0.0.0",22);
System.out.println("session is ::::"+session.getHost());
// username and password will be given via UserInfo interface.
UserInfo ui = new MyUserInfo("Lab#123", null);
//UserInfo ui = new MyUserInfo(password, null);
session.setUserInfo(ui);
session.setPassword("Lab#123");
Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(40000);
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand("ls");
channel.connect();
channel.run();
// get I/O streams for remote scp
OutputStream out=channel.getOutputStream();
InputStream in=channel.getInputStream();
String output="";
while (channel.isClosed()!=true) {
try {
output+=streamToString(in);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Output is :::"+output);
channel.disconnect();
session.disconnect();
}
public static String streamToString(InputStream input)throws Exception
{ String output = ""; while(input.available()>0) { output += ((char)(input.read())); } return output; }
public static OutputStream stringToStream(String charset) throws IOException{
byte[] bytes = charset.getBytes();
/*ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
InputStreamReader isr = new InputStreamReader(bais);*/
InputStream is = null;
OutputStream os = null;
try {
is = new ByteArrayInputStream(charset.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//byte[] buf = new byte[1024];
int numRead;
while ( (numRead = is.read(bytes) ) >= 0) {
os.write(bytes, 0, numRead);
}
return os;

Related

Running command using "exec" channel with JSch does not return any output

I am trying to execute a command on a Linux server using SSH from Android with JSch.
As far as I know I am connecting to the server, but when I attempt to retrieve the results of the command I am getting nothing.
Connect to server:
public class SSHCommand {
public static String executeRemoteCommand(
String username,
String password,
String hostname,
int port) throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, port);
session.setPassword(password);
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
// SSH Channel
ChannelExec channelssh = (ChannelExec)
session.openChannel("exec");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
channelssh.setOutputStream(baos);
// Execute command
channelssh.setCommand("ls");
channelssh.connect();
channelssh.disconnect();
return baos.toString();
}
}
Retrieve data:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String TAG = "TESTING";
new AsyncTask<Integer, Void, Void>(){
#Override
protected Void doInBackground(Integer... params) {
try {
Log.d(TAG, SSHCommand.executeRemoteCommand("username", "password", "192.168.0.1", 22));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute(1);
}
}
What am I missing here?
You disconnect immediately after you start the command, before any output is returned.
You have to wait for the "exec" channel to close (it closes once the command finishes).
See the official JSch example for the "exec" channel.
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
System.out.print(new String(tmp, 0, i));
}
if(channel.isClosed()){
if(in.available()>0) continue;
System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
Though to allow the command to reliably complete and to collect all output including the errors, see How to read JSch command output?
It worked for me after I put my crafted code after channelssh.connect();
while(true){
if(channelssh.isClosed()){
break;
}
}
So my completed function would be:
public static String executeRemoteCommand(
String username,
String password,
String hostname,
int port) throws Exception {
try{
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, 22);
session.setPassword(password);
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
// SSH Channel
ChannelExec channelssh = (ChannelExec) session.openChannel("exec");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
channelssh.setOutputStream(baos);
// Execute command
channelssh.setCommand("ls -al");
channelssh.connect();
while(true){
if(channelssh.isClosed()){
break;
}
}
channelssh.disconnect();
return baos.toString();
} catch (Exception e){
Log.e("Some Tag", e.getMessage());
return "ERROR";
}
}

Jsch java ssh client is not getting disconnected after command gets executed

I am using java ssh client (http://www.jcraft.com/jsch/) to connect to remote machine and execute the command.
The code is working fine till i connect to remote machine and execute the command. however, the issue is , the channel and session are not getting disconnected even after command executed successfully.
I have called session.disconnect and channel.disconnect as well but still the issue.
Here is my code:
JSch jsch = new JSch();
String host = null;
host = "192.168.102.211";
String privateKey = "C:\\test\\key";
String cmd = "a";
String command = "b";
jsch.addIdentity(privateKey);
Session session = jsch.getSession("user1", host, 22);
Channel channel = session.openChannel("shell");
UserInfo ui = new MyUserInfo() {
public boolean promptYesNo(String message) {
return true;
}
};
session.setUserInfo(ui);
session.connect(30000);
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
ps.println(cmd);
ps.println(command);
ps.close();
InputStream in = channel.getInputStream();
byte[] bt = new byte[1024];
while (in.available() > 0) {
// int i = in.read(bt, 0, 1024);
for (int i = in.read(); i >=0; i--)
{
String str = new String(bt, 0, i);
System.out.print(str);
}
break;
}
if (channel != null) {
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
}
Please suggest
Update your question with a relevant code.
just a hint, you should do something like.
} finally {
if (channel != null) {
Session session = channel.getSession();
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
}
I have similar error I change my code to that
first I have declare session and channel
static Session session = null;
static Channel channel = null;
And this the connation code
public static OutputStream puttyConnection(String user, String hostName, String password)
throws JSchException, IOException {
session = new JSch().getSession(user, hostName, 22);
session.setPassword(password);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
channel.connect();
return ops;
}
and in the finish of my running code I use to disconnect like that
if (channel != null) {
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
I encountered a similar problem, realizing that the channel could only be disconnected if it was closed. So I used the while loop to check if the channel is closed and then I was able to disconnect the channel without any problem.
while (true){
if(channel.isClosed()){
channel.disconnect();
break;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

JSch stdout not appearing when running from command line

When I run the following code which is a modified block from one of the jsch examples. The ssh command works but although I can see subsequent stdout/stderr in eclipse or jdb I cannot see output when I run outside eclipse. I assume that stdout and/or stderr has been redirected but I don't know how to cancel the redirection.
Thanks
John Ross
public void runSSHCommand(final String command, final String user, final String pwd,
final String host)
{
try
{
final JSch jsch = new JSch();
final Session session = jsch.getSession(user, host, 22);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(pwd);
session.connect();
final Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
final InputStream in = channel.getInputStream();
channel.connect();
final byte[] tmp = new byte[1024];
while (true)
{
while (in.available() > 0)
{
final int i = in.read(tmp, 0, 1024);
if (i < 0)
{
break;
}
//System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed())
{
if (in.available() > 0)
{
continue;
}
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try
{
Thread.sleep(1000);
} catch (final Exception ee)
{
}
}
channel.disconnect();
session.disconnect();
} catch (final Exception e)
{
System.out.println(e);
}
return;
}

Copy a file on remote server from one directory to other using Jsch

I am trying to copy a file on server from one directory to another one using Jsch. I am using SFTP protocol put and get methods to accomplish this task. I am doing this way as I dont have shell access to the server. Below is my code sample and the exception that I am getting. Can someone please let me know how to resolve it.
OutputStream outputStream = null;
InputStream inputStream = null;
try
{
JSch jsch = new JSch();
session = jsch.getSession(USER,HOST,PORT);
session.setPassword(PASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications", "password");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp)channel;
inputStream = channelSftp.get(fromFilename);
channelSftp.put(inputStream,toFilename);
} catch(Exception e){
e.printStackTrace();
} finally {
if(inputStream != null)
inputStream.close();
if(outputStream != null)
outputStream.close();
channelSftp.exit();
channel.disconnect();
session.disconnect();
}
Here is the exception
4: java.io.IOException: error: 4: RequestQueue: unknown request id 12
at com.jcraft.jsch.ChannelSftp._put(ChannelSftp.java:689)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:540)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:492)
You have to do the get() operation in a one channel and put() operation in another channel. That works. Here is my code.
public void cp (Session session, String source, String target) throws Exception {
log.info("COMMAND: cp " + source + " " + target);
if (!session.isConnected()) {
log.error("Session is not connected");
throw new Exception("Session is not connected...");
}
Channel upChannel = null;
Channel downChannel = null;
ChannelSftp uploadChannel = null;
ChannelSftp downloadChannel = null;
try {
upChannel = session.openChannel("sftp");
downChannel = session.openChannel("sftp");
upChannel.connect();
downChannel.connect();
uploadChannel = (ChannelSftp) upChannel;
downloadChannel = (ChannelSftp) downChannel;
FileProgressMonitor monitor = new FileProgressMonitor();
InputStream inputStream = uploadChannel.get(source);
downloadChannel.put(inputStream, target, monitor);
} catch (JSchException e) {
log.error("Auth failure", e);
throw new Exception(e);
} finally {
if (upChannel == null || downChannel == null) {
System.out.println("Channel is null ...");
}else if (uploadChannel != null && !uploadChannel.isClosed()){
uploadChannel.exit();
downloadChannel.exit();
uploadChannel.disconnect();
downloadChannel.disconnect();
}else if (!upChannel.isClosed()) {
upChannel.disconnect();
downChannel.disconnect();
}
session.disconnect();
}
}

Having trouble issuing Java command with Jsch

I'm having an issue running a java commend via jsch. This java command works fine if I execute it in a SSH session via putty, but when executed in my code returns an exit status of 127.
The command is this:
sshCommManager.sendCommand("cmd /c java -Xms256M -Xmx1024M -jar FileCatalystTester.jar -basic /Y");
With the sendCommand function being a derivative of the exec example. Here is the entire SSHCommManager I wrote:
public class SSHCommManager extends Observable{
private JSch jsch; //ssh library
private static String user = "what";
private static String password = "youwhat";
//private static String host = "192.168.1.1";
private static SSHCommManager sshCommManager;
private Session session;
private Channel channel;
public boolean commsConnected = false;
private int aPort = 22;
private SSHCommManager() {
this.addObserver(MainUI.getInstance());
}
public static SSHCommManager getInstance() {
if (sshCommManager == null) {
sshCommManager = new SSHCommManager();
}
return sshCommManager;
}
public void init(String aHost) {
try {
jsch = new JSch();
//System.out.println("Getting ssh session...");
session = jsch.getSession(user, aHost, aPort);
session.setX11Host(aHost);
session.setX11Port(aPort + 6000);
//System.out.println("Getting user info...");
session.setPassword(password);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
System.out.println("Connecting to ssh...");
session.connect(30000);
if (session.isConnected()) {
commsConnected = true;
} else {
commsConnected = false;
}
System.out.println(commsConnected);
} catch (Exception e) {
System.out.println(e);
}
}
public void sendCommandTest(String aCommand) {
try {
Channel channel1=session.openChannel("shell");//only shell
System.out.println("Sending Test command: "+ aCommand);
channel1.setOutputStream(System.out);
PrintStream shellStream = new PrintStream(channel1.getOutputStream()); // printStream for convenience
channel1.connect();
shellStream.println(aCommand);
} catch (Exception e) {
System.out.println(e);
}
if (channel.isClosed()) {
System.out.println("exit-status: "
+ channel.getExitStatus());
}
}
public String sendCommand(String aCommand){
InputStream in = null;
OutputStream out = null;
StringBuilder commandOut = new StringBuilder();
try {
channel = session.openChannel("exec");
System.out.println("Sending command: " + aCommand);
((ChannelExec) channel).setCommand(aCommand);
//channel.setInputStream(System.in);
channel.setInputStream(null);
//channel.setOutputStream(System.out);
((ChannelExec) channel).setErrStream(System.err);
in = channel.getInputStream();
//out = channel.getOutputStream();
channel.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)break;
//System.out.print(new String(tmp, 0, i));
//System.out.println(channel.getInputStream().toString());
commandOut.append(new String(tmp, 0, i));
//setChanged();
//notifyObservers(System.err.toString() + "\n");
}
if (channel.isClosed()) {
System.out.println("exit-status: "
+ channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
throw new JSchException("Cannot execute remote command: " + aCommand + " : " + ee.getMessage());
}
}
//channel.disconnect();
//session.disconnect();
} catch (Exception e) {
System.out.println(e);
}
return commandOut.toString();
}
public void cleanupSSH() {
channel.disconnect();
session.disconnect();
}
public boolean isCommsConnected() {
return commsConnected;
}
}
...any thoughts or help would be appreciated as I cannot figure out why that java command won't work. I've tried everything, including putting in the direct paths for both java and the .jar file I'm trying to execute.
Following program work to access remote SSH server
private String userName = "xxxx";
private String password ="xxxx";
private String hostName = "xxx.xxx.xxx.com";
private int port = 22;
private String sdstestCommand = "java -Xms256M -Xmx1024M -jar MyProgram";
public void testconnect () throws JSchException, IOException {
JSch jsch = new JSch();
Session session = jsch.getSession(userName, hostName, port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(password);
session.connect();
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(sdstestCommand);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
System.out.println("Unix system connected...");
byte[] tmp = new byte[1024];
while (true){
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
String line = new String(tmp, 0, i);
System.out.println("Unix system console output: " +line);
}
if (channel.isClosed()){
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee){
//ignore
}
}
channel.disconnect();
session.disconnect();
}
}

Categories

Resources