0

I am working on on a tool to connect to a remote server using jcraft.JSch (ssh to Unix server) and return the output and display its output (something like putty, but iam not keen on Plink or any third party thing). The code works fine when channel input outputs are System.in and System.out and the program is just a console java application. But when I try with SWT controls, it was having problem as explained in How to Map System.out and System.in to SWT controls

so, I believe its something anout the INFO and ERR tagging (which i will deal with later), anyways i changed the approach. now iam feeding commands through a SWT Text input. its working fine for single line outputs. but not for multi line.

enter image description here

The code which triggers the connection to shell and sends commands is as follows.

        public void widgetSelected(SelectionEvent e) {
        String command=CmdText.getText();
        System.out.println("runButton.widgetSelected:Command Obtained by buton is:"+command);
        if ( command.equals("") )
        {
           MessageDialog.openInformation(dialogShell,"Information","Please Eneter a Command!");
           return;
        }
        else if (command.contains("@"))
        {
            channel=CommandHandler.openshell();
            LogText.append("Connected to - :"+command+"\n>");
        }
        else
        {
            LogText.append(command+"\n");
            String outputstring="";
            try
            {
                 BufferedReader dataIn = new BufferedReader(new InputStreamReader(channel.getInputStream()));
                 DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());  

                 dataOut.writeBytes(command+"\n");
                 dataOut.flush();

                 String line="";
                 outputstring=""+line;
                 while ( line != null) {
                     try
                     {
                        line = dataIn.readLine();
                        line = dataIn.readLine();
                        LogText.append("<CommandResult>:"+line+"\n");
                        return;
                     }
                     catch (IOException e1) { B24IDEConsole.WriteLog("RemoteCall.connect_execute", e1.getMessage()); }
                     outputstring=outputstring+line;
                 }
            }
            catch(Exception e1){ B24IDEConsole.WriteLog("RemoteCall.connect_execute", e1.getMessage()); }
            LogText.append("<EndOfCommand>:"+outputstring+"\n");
        }
    }

When i remove return in the while loop the dialog and the eclipse (triggering the dialog) becomes un-responsive and i have to kill them both.

Any Help is appreciated, thank you for your time.

Community
  • 1
  • 1
  • Looks like you need to run the command in a background thread and use Display.asyncExec to feed the output to the text control. – greg-449 Aug 24 '15 at 07:29
  • Thank you for the comment, but are you suggesting that i start a `shell` (in background) execute the command and `exit` and display the output on SWT ?. if so, i cannot do that because the user might've set some environment variables or some previous command's return code, which will be lost if i do that. what i observed without `return` is that i am able to read all the output lines but once that is done. and when i try to read more (with dataIn.readLine() ) the debug thread vanishes and the eclipse window (the one i am debugging) becomes unresponsive. please advice. – Nauduri Venkata Ravi Rama Sast Aug 24 '15 at 08:16

1 Answers1

0

There are two things i was missing in the above code.

  1. getOutputStream and getInputStream were getting called after channel.connect while Jsch documentation says it shouldnt be ref: http://epaul.github.io/jsch-documentation/simple.javadoc/com/jcraft/jsch/Channel.html
  2. dataIn.available is a better test if any more data is available from the server or not. thanks to Sending commands to server via JSch shell channel.

updated code is

                 InputStream dataIn = CommandHandler.getdatain();
                 OutputStream dataOut = CommandHandler.getdataout();
                 //dataOut.write(command.getBytes()+"\n");
                 byte[] inputbytes = command.getBytes();
                 dataOut.write(inputbytes,0,inputbytes.length);
                 dataOut.flush();
                 while (true) {
                        boolean readoutput=false;
                        while (dataIn.available() > 0) {
                            readoutput=true;
                            byte[] buffer=new byte[1024];
                            int i = dataIn.read(buffer, 0, 1024);
                            if (i < 0) {
                                System.out.print("No more data available!");//It is printing the response to console
                                break;
                            }
                            LogText.append(new String(buffer, 0, i));
                            //LogText.append(":"+new String(buffer, 0, i)+"\n>");
                            System.out.print(new String(buffer, 0, i));//It is printing the response to console
                        }
                        System.out.println(dataIn.available()+"done");
                        if ( readoutput )
                        {
                            if ( dataIn.available() == 0 )
                            {
                                System.out.print("Read all the data and no nore is available, hence exiting!\n");//It is printing the response to console
                                break;
                            }
                        }
                        if ( channel.isClosed() ) {
                            System.out.println("exit-status: " + channel.getExitStatus());
                            break;
                        }
                        try{Thread.sleep(1000);}catch(Exception ee){}
                 }

break is still a problem but looks like can be fixed for now.

Community
  • 1
  • 1