33850

JSch channel.disconnect prevent logs from printing

Question:

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:

<blockquote> *****NEW ONE*****$$$$$**$$########Starting...

Before Disconnected Here exit-status: 0

</blockquote>

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

<blockquote>

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

</blockquote>

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?

<strong>Edit</strong><br /> Also, I'm not able to see the syouts from my finally block!!

Answer1:

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

<a href="http://epaul.github.io/jsch-documentation/javadoc/com/jcraft/jsch/ChannelExec.html#setErrStream%28java.io.OutputStream,%20boolean" rel="nofollow">Javadoc</a>

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.

Answer2:

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

Recommend

  • sharing servlet context across web applications in same server
  • How do you store information in session memory in spring mvc to fetch later?
  • Connection pool. call a procedure each time an operation is made
  • Caused by: java.lang.IllegalStateException: EntityManagerFactory must not be null
  • Exception coming while running JSP
  • Persistence.createEntityManagerFactory takes ages
  • Secure FTP using private key authentication in java
  • Return a custom auth response object from ServiceStack authentication
  • Hibernate Session Closed Exception after fast subsequent requests
  • Is LoginInterceptor Work in Struts2?
  • How to make that GridView buttons update and delete just only visible for admins?
  • Hibernate persist without transaction
  • Session timeout upon refresh at login page
  • How to exclude a method to be @Transactional?
  • Conversion of my alfresco javascript file into java class [duplicate]
  • How to verify that data source is valid and configured properly?
  • play 2.1.1: Unable to rollback transaction with ebean orm
  • JAVA Change JSESSIONID cookie
  • JSF View- returning null on actions do not update the view
  • Unable to get Hadoop job information through java client
  • Apache HttpClient able to communicate over HTTPS when DIRECT but not via PROXY error: javax.net.ssl.
  • SpringSession DefaultCookieSerializer.setJvmRoute works, but HttpServletRequest does not have the jv
  • array from php to JavaScript
  • Session management in GWT client side
  • Restructure php contact form
  • Net-ssh session timeout
  • `docker cp` doesn't copy file into container
  • mCamera.setpreview{@override onPreviewFrame() } not work
  • How to check disabled jobs with Jenkins server?
  • Python Paramiko send CTRL+C to an ssh shell
  • Syntax error near unexpected token 'elif'
  • Building jamvm 1.5.4 on OS X Lion
  • How can I get the full list of running processes on a Mac from a python app
  • pip in virtualenv gets ConnectTimeoutError
  • Dynamically switching connect in Modelica
  • bad substitution shell- trying to use variable as name of array
  • Check for zero lines output from command over SSH
  • nonblocking BIO_do_connect blocked when there is no internet connected
  • Redux Form - Not able to type anything in input
  • Get history of file changes from TFS to implement custom “blame”-behaviour of exceptions