How to edit the existing file on the linux server using jsch - java

I have a file on the linux server that contains the system date of the application.
The file name is "abc.property." and the file contains the systemdate parameter which application reads.
e.g the content of the file is below:-
1.SYSTEMDATE= 20162201 160
2.ABC
3.XYZ
4.CCC
I want to write a java program that will connect to the server using JSCH and allow me to change the system date through the application.
I already have a code to connect to the server and read the content.
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
session.sendKeepAliveMsg();
sftpChannel.connect();
session.sendKeepAliveMsg();
sftpChannel.cd("path");
InputStream out= null;
out= sftpChannel.get(remoteFile);
BufferedReader br = new BufferedReader(new InputStreamReader(out));
String line;
session.sendKeepAliveMsg();
System.out.println(workingDir);
Can any one help me on this?? i am new to jsch programming.
Thank you in advance.

Related

JSch not uploading complete file to remote SFTP server, only partial

I am trying to use the Jsch library to transfer a locally created XML file (marshalled from a Java object using JAXB) to a remote server. However, the file only gets partially uploaded. It is missing the end tag and an arbitrary amount of characters at the end.
My code looks like this (TradeLimits is a JAXB annotated Java class)
TradeLimits limits = getTradeLimits(); //complex object with many fields
JSch jsch = new JSch();
jschSession = jsch.getSession(username, remoteHost);
//to avoid unknown host issues
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
jschSession.setConfig(config);
jschSession.setPassword(password);
jschSession.setPort(22);
jschSession.connect();
ChannelSftp channelSftp = (ChannelSftp) jschSession.openChannel("sftp");
channelSftp.connect();
jaxbContext = JAXBContext.newInstance(TradeLimits.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); //for pretty print
marshaller.marshal(limits, channelSftp.put(limitUploadPathString)); //this uploads only partial xml file to sftp server
marshaller.marshal(limits, System.err)); //THIS WORKS CORRECTLY AND THE FULL XML IS PRINTED!
channelSftp.disconnect();
channelSftp.exit();
Note how this cannot be a JAXB issue because it will print the complete XML elsewhere, but only partial is uploaded to remote server. What can possibly be the issue? Thanks in advance!
Always ensure you flush/close an OutputStream when you are done writing to it.
try(OutputSteam fileStream = channelSftp.put(limitUploadPathString)) {
marshaller.marshal(limits, fileStream);
}

FTPSClient, What values to give for Remote and Local

I am new to FTPSClient i trying to connect to a FTPS created in my laptop. i don't exactly what some of the methods working and their parameter meaning.
For example,
In my code i have created a FTPSClient as below:
FTPSClient ftps =new FTPSClient();
Then connected to a server use connect() method with ip address.
ftps.connect("172.xx.xx.xxx");
After every step i will check the reply code using.
ftps.getReplyCode();
In the below code i know that
username = system username
password = the password to login
ftps.login(username, password);
In the my system in Internet Information Service(IIS). Created an ftp server with ssl and given the below directory to share.
C:\Users\karan-pt2843\Desktop\FTPS
Want to send the file in below directory to the server.
D:\sam.txt
Now i want to store a file in the server in the given above directory and i tried using
remote="";
local="";
InputStream input;
input = new FileInputStream(local);
ftps.storeFile(remote, input);
input.close();
I don't know what value to give for remote and local. please help me with the values to give on them and the what happens internal.
// Use passive mode as default because most of us are
// behind firewalls these days.
ftps.enterLocalPassiveMode();
...
String remote = "samFromClient.txt"; //Place on FTP
String input = "D:/sam.txt" //Place on your Client
//Your FTP reads from the inputstream and store the file on remote-path
InputStream input = new InputStream(new FileInputStream(input));
ftps.storeFile(remote, input);
input.close();
ftps.logout();
...
Taken from: Apache example

com.jcraft.jsch.JSchException: java.io.IOException: Pipe closed

I am trying to copy a file over SFTP to another Host using Jcraft JSch (http://www.jcraft.com/jsch/). I am getting below error:
Connecting via SSH to somehost:22
com.jcraft.jsch.JSchException: java.io.IOException: Pipe closed
at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:315)
at com.jcraft.jsch.Channel.connect(Channel.java:152)
at com.jcraft.jsch.Channel.connect(Channel.java:145)
Relevant code is below:
Channel channel = null;
ChannelSftp channelSftp = null;
Exception cause = null;
try {
connect();
channel = session.openChannel( "sftp" );
channelSftp = (ChannelSftp)channel;
channelSftp.connect();
assert channelSftp != null;
try {
channelSftp.ls( destDir );
} catch( SftpException sftpEx ) {
// Create destination folder, if it does not exist
execCommand( "some command" + destDir );
}
This was all good since last week, upgrading to latest jcraft version doesn't work. I referred to this and this (refer last comment on page), but could not reach to root cause. Any help?
SSH was working without any issue. Problem was with SFTP module path in SSH config. Below link was not accessible.
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server

How to provide sftp password through Java

I am using JSCH API to invoke shell commands from java. I am trying to invoke sftp command like this :
Channel channel = (ChannelShell)getSession().openChannel("shell");
channel.connect();
PrintStream out = new PrintStream(channel.getOutputStream());
out.println("#!/bin/bash");
out.println("sftp akumar#sindh");
out.flush();
On Java console i see that it is connecting to this sindh server and then it asks for password.
Connecting to sindh...
akuamr#sindh's password:
How do i provide password to it. I tried
out.println("sftp akumar#sindh");
out.println("password123")
But this dosen't work out. Thanks in advance.
You need to set the password in the Session before connecting:
JSch jsch=new JSch();
Session session = jsch.getSession("akumar", "sindh");
session.setPort(22);
session.setPassword("password123");
session.connect();
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
channel.connect();
And then you can use the channel to execute sftp commands.

SFTP: IOException while reading a file with java

I am using com.jcraft.jsch library to read .xls files from an SFTP server. Following is the code to connect to server.
session = jsch.getSession(username, host);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(password);
session.connect();
sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
I am using sftpChannel.get(file) to retrieve inputStream to the file. This inputstream is then used to instantiate XSSFWorkbook as shown below:
XSSFWorkbook workbook = new XSSFWorkbook(in);
Problem 1:
When I run the app, it seems to get stuck on the above line for some time (say 5 minutes) and then it throws java.io.IOException: Pipe closed error.
The xls file I am trying to read is 800kb and it works fine when run from local machine.
Problem 2:
The app is designed to process files sequentially. So, if first file fails with IOE, rest of the files also fail as the connection is timed out. To prevent this, I put the below code to check and re-connect:
if(null == session || !session.isConnected()){
log.debug("Session is not connected/timed out. Creating a new session");
openSftpSession();
log.debug("New session is created");
}
//openSftpSession() is the code to create a new session as explained in the beginning of the question.
When this code gets executed, following exception gets thrown:
java.io.IOException: error: 4: RequestQueue: unknown request id 1028332337
at com.jcraft.jsch.ChannelSftp$2.read(ChannelSftp.java:1407)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at java.io.PushbackInputStream.read(PushbackInputStream.java:186)
//More lines
edit : code to retrieve input stream
public InputStream getInputStream(String folder, String file) throws Exception{
sftpChannel.cd(root + folder);
log.debug("current directory:" + sftpChannel.pwd());
log.debug("File :" + folder + " " + file);
return sftpChannel.get(file);
}
Can anyone please help me get over this? I believe an alternate approach to prevent timeout is to download the file in some temp directory and process. However, I don't really want to do that.
Thanks in advance.
Have you checked to see whether the approach you describe (download into temp file) works? Just to verify that your inputstream is ok.. How long does it take to download into a local file over that connection?
If you don't want to manage a temp file you could always pull it into a byte[] in memory, so long as you don't have to scale to much more than 800kbs.. Use Apache Commons as such:
InputStream in = sftpChannel.get(file);
byte[] inBytes = org.apache.commons.io.IOUtils.toByteArray(in)
ByteArrayInputStream inByteStream = new ByteArrayInputStream(inBytes)
XSSFWorkbook workbook = new XSSFWorkbook(inByteStream);
As for the Request Id, it looks like the old session/channel is still trying to do a read but is no longer able to. Maybe you aren't closing out that session/channel properly. From the openSftpSession() code it looks like you would only be overwriting the references without properly shutting them down.

Categories

Resources