I am trying to use localhost as SFTP server. I'm using Jsch library of Java to implement SFTP with SSH2. The following code upload a text file to a directory on local machine with sftp.
But I cannot connect to localhost.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class Server{
public Server() {
}
public static void main(String[] args) {
String SFTPHOST = "localhost";
int SFTPPORT = 22;
String SFTPUSER = "root";
String SFTPPASS ="";
String SFTPWORKINGDIR = "D:\\Upload";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
try{
JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER,SFTPHOST,SFTPPORT);
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp)channel;
channelSftp.cd(SFTPWORKINGDIR);
File f = new File("trial.txt");
channelSftp.put(new FileInputStream(f), f.getName());
}catch(Exception ex){
ex.printStackTrace();
}
}
}
"Connection refused" means that there is no process listening for connections at the IP address and port which you're trying to connect to. In this case, the most likely explanation is that your SSH server process isn't running, or perhaps it has been configured to listen on some other port than port 22.
It looks like this is a Windows system? If that's the case, you could check the task manager to see if there is a copy of the sshd program running. To see if something is listening on port 22, open a command-line window and run netstat -an. Then look for a line like this:
TCP 0.0.0.0:22 0.0.0.0:0 LISTENING
^^-- Listening on port 22
If sshd isn't running, it needs to be started. If it is running, but nothing is listening on port 22, then you should examine sshd's configuration file.
If you need further help starting sshd, you should ask on https://superuser.com/.
Related
The intention is to stream the log during runtime on a specific host:port, so that the logs are accessible to users outside the running system, from browser.
As you can see, i have created a simple SocketHandler for java8 logging(java.util.logging), is there something that i have missed?
import java.net.MalformedURLException;
import java.net.URL;
import java.io.IOException;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SocketHandler;
import java.util.logging.XMLFormatter;
public class Main {
public static void main(String[] args) throws Exception {
Logger logger = Logger.getLogger("concrete.log");
SocketHandler handler = new SocketHandler("HOSTNAME", 19004);
LogRecord logRec = new LogRecord(Level.INFO, "Log recorded");
handler.publish(logRec);
handler.setFormatter(new XMLFormatter());
logger.addHandler(handler);
logger.info("socket handler info message");
}
}
When i run the code, i see the following exception, i have tried checking the system firewall settings on both local(mac/windows) and remote(Linux) and seen that the settings do not block 19004 port
Exception in thread "main" java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
at java.net.Socket.connect(Socket.java:606)
at java.net.Socket.connect(Socket.java:555)
at java.net.Socket.<init>(Socket.java:451)
at java.net.Socket.<init>(Socket.java:228)
at java.util.logging.SocketHandler.connect(SocketHandler.java:167)
at java.util.logging.SocketHandler.<init>(SocketHandler.java:154)
at Main.main(Main.java:16)
UPDATE
As suggested by bosowski
When i create Socket to listen to a specific port, the log messages are getting printed on the console of the host. However, am unable to access hostname:port for the log to be streamed from the browser. Is there anything specific that needs to be performed after this step?
Please let me know
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args)
{
try {
ServerSocket ss = new ServerSocket(19004);
Socket soc = ss.accept();
DataInputStream dis
= new DataInputStream(soc.getInputStream());
String str = (String)dis.readUTF();
System.out.println("message= " + str);
ss.close();
}
catch (Exception e) {
System.out.println(e);
}
}
}
SocketHandler does not open up a port to connect to, if that's what you're assuming. It tries to connect to the specified host and port, so you need to have a port that is listening on the host that you are trying to connect to.
https://docs.oracle.com/javase/8/docs/api/java/util/logging/SocketHandler.html#SocketHandler-java.lang.String-int-
<handler-name>.host specifies the target host name to connect to (no default).
<handler-name>.port specifies the target TCP port to use (no default).
If you do indeed have a listening TCP port on the hostname that you're trying to connect to, you can try running sudo nmap -F hostname to check if the port is indeed accessible from your machine.
I'm trying to SFTP a file from a server using JSCH in java. Though I succeeded in doing that, I notice a drastic slow down in my performance (transfer rate) than compared to, doing the same operation directly through my PUTTY.
At present, I used channel.get(src,dst) to get the file from server
Any reason or solution would be of great help!
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class SFTPExample {
public static void main(String args[]) throws Exception {
String srcFile=fl.getSrcFile();
String tarFile=f1.getTarFile();
JSch jsch = new JSch();
jsch.setKnownHosts(knownHostsFilename);
Session session = jsch.getSession(config.getUser(),config.getSftpHost());
session.setPassword(config.getpassword());
session.connect();
Channel Channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpchannel=(ChannelSftp) channel;
sftpChannel.get(srcFile, tarFile);
sftpChannel.exit();
session.disconnect();
}
}
Hi I'm triying execute any hadoop command like "hadoop fs -ls" throught a Java app remotely. I have my Java app in my local machine and Hadoop in a VM.
First I make a ssh connection and work. Also I can execute a linux command throught the java code it was working ,but hadoop commands are not working,it throws the following Error .Any idea to Execute hadoop commands?
this is my jsch program
package com.jsch.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class Jschtest {
public static void main(String[] args){
String command="hadoop fs -ls /";
try{
String host = "192.168.3.197"; //IP address of the remote server
String user = "user"; // Username of the remote server
String password = "HDP123!"; // Password of the remote server
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);;
session.setPassword(password);
session.connect();
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream input = channel.getInputStream();
channel.connect();
System.out.println("Channel Connected to machine " + host + " server
with command: " + command );
try{
InputStreamReader inputReader = new InputStreamReader(input);
BufferedReader bufferedReader = new BufferedReader(inputReader);
String line = null;
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
bufferedReader.close();
inputReader.close();
}catch(IOException ex){
ex.printStackTrace();
}
channel.disconnect();
session.disconnect();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
This is my Error Message
Channel Connected to machine 192.168.3.197 server with command: hadoop fs -ls /
bash: hadoop: command not found
Open your bashsrc and add the Hadoop BIN folder path to the PATH variable in the file.
Run source ~/.bashrc command.
Alternatively, you can make the following change to the command variable :
command = usr/local/hadoop/bin/hadoop fs -ls
If you are getting this error "bash: hadoop: command not found" means. Hadoop is not recognized by the OS
You need to update ".bashrc" file with hadoop home directory
I'm trying to upload a file via Secure FTP with org.apache.commons.net.ftp.FTPClient but I receive "java.net.NoRouteToHostException: No route to host" when connecting. The host is pingable and I can even read/write files with my FTP user via Filezilla SFTP connection to it. No firewall active in my router.
What could be the problem?
My specs: Mint 17 x64, Java 7, router Netgear DGND4000 (maybe this help)
This is the code:
package it.eproject.pdf;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.ftp.FTPClient;
public class Test {
public static void main(String[] args) {
System.out.println("Start upload file");
String sourceFile = "pdf/d00001.pdf";
String pdfName = "d00001.pdf";
String pdfDestFolder = "/pdf";
String ftpHost = "itsa.pingable.host";
String ftpUsername = "username";
String ftpPassword = "password";
FTPClient ftp = new FTPClient();
try {
ftp.setConnectTimeout(5000);
ftp.connect(ftpHost);
ftp.login(ftpUsername, ftpPassword);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
InputStream input = new FileInputStream(new File(pdfName));
ftp.storeFile(pdfDestFolder + pdfName, input);
ftp.logout();
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Done");
}
}
and this the exception:
java.net.NoRouteToHostException: No route to host
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:182)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:203)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:296)
at it.eproject.pdf.Test.main(Test.java:26)
SFTP (Secure FTP) is not the same as FTPS (FTP over SSL). Make sure you're not mixing apples and oranges.
I suppose Apache Commons libs does not provide SFTP APIs, so I switched to JCraft Jsch (http://www.jcraft.com/jsch/) and it works like a charm.
I am using JSch for retrieving a file from a remote machine by SFTP. Here is the code
public class TestSFTPinJava {
public static void main(String args[]) {
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession("username", "sftp.abc.com", 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword("password");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
System.out.println("Directory:" + sftpChannel.pwd());
sftpChannel.cd("remoteDirectory/");
System.out.println("Directory after cd:" + sftpChannel.pwd());
sftpChannel.get("remote-data.txt");
sftpChannel.put("C:\\Users\\mona\\Documents\\local-copy.txt");
sftpChannel.exit();
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
}
}
Now, I have two questions:
sftpChannel.get("remote-data.txt"); throws an exception:
no such file
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2297)
at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:1750)
at com.jcraft.jsch.ChannelSftp.get(ChannelSftp.java:1020)
at com.jcraft.jsch.ChannelSftp.get(ChannelSftp.java:995)
at TestSFTPinJava.main(TestSFTPinJava.java:29)
I am not sure how to specify the location in my local system where the file will be saved.
sftpChannel.put("C:\\Users\\mona\\Documents\\localCopy.txt"); does not look right to me.
Please help with suggestions, Thanks!
Concerning your point 1, I suspect that the default directory after connecting is not what you expect. Try using an absolute remote path. Does sftpChannel.pwd() return the directory the file remote-data.txt is in on the remote machine ?
Concerning your point 2, looking at http://grepcode.com/file/repo1.maven.org/maven2/com.jcraft/jsch/0.1.42/com/jcraft/jsch/ChannelSftp.java#290 one sees that there is the following method in ChannelSftp:
public void put(String src, String dst)
which indeed has a source and destination file name argument.
I guess you had already a look the Jsch sftp example at http://www.jcraft.com/jsch/examples/Sftp.java ?
Simple example of app.
I get file from remote server (from /tmp/qtmp) and save it in local machine in the current path
package connector;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
public class Fetcher {
public void fetchFile(String username, String host, String passwd) throws JSchException, SftpException, IOException {
JSch conn = new JSch();
Session session = null;
session = conn.getSession(username, host, 22);
session.setPassword(passwd);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
ChannelSftp channel = (ChannelSftp)session.openChannel("sftp");
channel.connect();
//change folder on the remote server
channel.cd("/tmp/qtmp");
InputStream in = channel.get("testScp");
// set local file
String lf = "OBJECT_FILE";
FileOutputStream tergetFile = new FileOutputStream(lf);
// read containts of remote file to local
int c;
while ( (c= in.read()) != -1 ) {
tergetFile.write(c);
}
in.close();
tergetFile.close();
channel.disconnect();
session.disconnect();
}
}
i had a similar issue, i was trying to get some files from a server where everything was fine, but i was getting always this error:
sftpChannel.get("fil1.txt","file1.txt")
error message:
2: No such file
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846)
at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2198)
at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2215)
at com.jcraft.jsch.ChannelSftp.get(ChannelSftp.java:913)
at com.jcraft.jsch.ChannelSftp.get(ChannelSftp.java:873)
...
I was listing properly all the elements of the directory by using
java.util.Vector v1 = sftpChannel.ls(dir);
I think that was that confused me, that i was able to read the content of the directory by using the ls command, when you want to get / put files make sure you move first by using "cd".
The solution was to use the next command to move to the directory that contains my files using a simple cd command:
sftpChannel.cd(dir);
Hope this helps, i took my sometime to figure it out. jojo.
Lessons learned:
1.- ls can read any directory no matter if you are not inside of it.
2.- To get and put files always make sure you are in the directory that contains the files by using cd.