JSch channel.disconnect предотвращает печать журналов

Я запускаю сценарий оболочки на удаленной машине, используя JSch, и печатаю журналы команд в своем файле журнала, используя канал JSch. Проблема в том, что когда сценарий заканчивается, я делаю channel.disconnect, и вскоре после отключения System.out перестает печатать в файл журнала. Вот код:

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;
    }

Строки из файла журнала:

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

Перед отключением Здесь статус выхода: 0

Если вы видите в методе, который я вставил выше, напечатанный sysout на самом деле находится чуть выше «channel.disconnect». Тот, что ниже, не печатается! Все работает правильно, и общий результат соответствует моим ожиданиям.

System.out.println("Перед отключением здесь exit-status: "+exitStatus);
channel.disconnect();
System.out.println("Отключено здесь exit-status: "+exitStatus);

Все работает правильно, и общий результат соответствует моим ожиданиям. Единственная проблема в том, что журнал зависает. Где я ошибаюсь?

Изменить
Кроме того, я не вижу syouts из моего блока finally!!


person Adi    schedule 26.11.2013    source источник


Ответы (2)


Скорее всего, это связано с этой строкой:

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

Сделав это, вы привязали поток System.err к потоку канала. И согласно документации, по умолчанию поток закрывается при отключении канала. Вы не говорите, на какой платформе вы работаете, но я думаю, что большинство платформ определенным образом соединяют System.err и System.out, поэтому Jsch, скорее всего, закрывает System.out при отключении. Вы можете попробовать сделать это, чтобы JSch не закрыл поток:

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

Javadoc< /а>

Даже если это сработает, я думаю, что подключение к System.err, как это, немного рискованно. Я думаю, что более безопасным было бы создать поток, который записывает в файл журнала напрямую, а не через System.err.

person kaliatech    schedule 26.11.2013
comment
ВОТ ЭТО ДА!! работал безупречно. Puff Я пропустил это. Большое спасибо kaliatech за быстрый ответ. Обязательно применю то, что вы предложили!! - person Adi; 27.11.2013

Это из-за

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

И когда вы отключаете канал, подключенные потоки также отключаются.

Поэтому, пожалуйста, напишите следующее заявление перед отключением канала:

((ChannelExec)channel).setErrStream(null);
person Abhishek Sharma    schedule 13.05.2014