JSch channel.disconnect prevent logs from printing

醉酒当歌 提交于 2019-12-13 01:50:06

问题


I'm running shell script on a remote machine using JSch and printing the command logs in my log file using JSch channel. Problem is that as the script ends, I do a channel.disconnect and soon after disconnect, the System.out stop printing into the log file. Here is the code:

private int runShellScript(HashMap bundleDetails) {
        int exitStatus = -1;
        Channel channel = null;
        Session session = null;
        try {
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");

            String host = (String) bundleDetails.get("host");
            String userName = (String) bundleDetails.get("userName");
            String password = (String) bundleDetails.get("password");
            String bundleName = findFileName((String) bundleDetails.get("bundleName"));

            String sourceLocation = (String) bundleDetails.get("sourceLocation");
            String logFileName = findFileName((String) bundleDetails.get("logFileName"));

            String targetLocation = (String)bundleDetails.get("targetLocation");            

            String command1 = "sh "+(String) bundleDetails.get("targetIndexerLocation") + (String) bundleDetails.get("deployScript")+" "+
                                    targetLocation + bundleName + " " +
                                    targetLocation + logFileName;
            JSch ssh = new JSch();
            session = ssh.getSession(userName, host, 22);
            session.setConfig(config);
            session.setPassword(password);
            session.connect();

            channel = session.openChannel("exec");
            ((ChannelExec)channel).setCommand(command1);
            channel.setInputStream(null);
            ((ChannelExec)channel).setErrStream(System.err);
            InputStream in=channel.getInputStream();
            channel.connect();
            byte[] tmp=new byte[1024];
            while(true){
                //System.out.println("inside while second");
                  while(in.available()>0){
                    int i=in.read(tmp, 0, 1024);
                    if(i<0)break;
                    System.out.print("*****NEW ONE*****$$$$$**$$########"+new String(tmp, 0, i));
              }
                  if(channel.isClosed()){
                      exitStatus = channel.getExitStatus();
                     System.out.println("Before Disconnected Here exit-status: "+exitStatus);
                      channel.disconnect();
                    System.out.println("Disconnected Here exit-status: "+exitStatus);
                    break;
                  }
            }       
            //logger("runShellScript", "END");
            System.out.println("***** out of infinite loop");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Copy to remote location failed.... ");
        }finally{
            System.out.println("finally DISCONNECT channel and session");
            if(channel!=null && channel.isConnected()){
                channel.disconnect();
            }
            if(session!=null){
                session.disconnect();
            }           
            System.out.println("finally DISCONNECTED channel and session");

        }
        System.out.println("Before return exit-status: "+exitStatus);
        return exitStatus;
    }

The lines from log file:

*****NEW ONE*****$$$$$**$$########Starting... 

Before Disconnected Here exit-status: 0

If you see in the method I pasted above, the sysout printed is actually the one just above the 'channel.disconnect'. The one below it is not printed! Al the functioning is correct and the overall output is what I expect

System.out.println("Before Disconnected Here exit-status: "+exitStatus);
channel.disconnect();
System.out.println("Disconnected Here exit-status: "+exitStatus);

All the functioning is correct and the overall output is what I expect. The only problem is that log freeze. Where am I going wrong?

Edit
Also, I'm not able to see the syouts from my finally block!!


回答1:


Most likely it is related to this line:

((ChannelExec)channel).setErrStream(System.err);

By doing that, you've tied the System.err stream to the channel stream. And per the documentation, by default, the stream is closed when the channel is disconnected. You don't say what platform you are running on, but I think most platforms connect System.err and System.out in certain ways, so Jsch is most likely closing the System.out when it disconnects. You might try doing this to prevent JSch from closing the stream:

((ChannelExec)channel).setErrStream(System.err, true);

Javadoc

Even if that does work though, I think hooking in to the System.err like this is a bit risky. I think safer design would be to create a stream that wrote to the log file directly, not via System.err.




回答2:


This is because of

((ChannelExec)channel).setErrStream(System.err);

And when you are disconnecting the channel, the connected streams are also being disconnected.

So please write the below statement before disconnecting the channel:

((ChannelExec)channel).setErrStream(null);


来源:https://stackoverflow.com/questions/20229001/jsch-channel-disconnect-prevent-logs-from-printing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!