Кто-нибудь знает о хорошей библиотеке для входа в SSH с Java.SSH-библиотека для Java
ответ
Java Secure Channel (JSCH) - очень популярная библиотека, используемая maven, ant и eclipse. Это с открытым исходным кодом с лицензией стиля BSD.
Это выглядит хорошо - есть ли какие-либо javadocs для него на все?Примерами являются несколько плохо написанный код колебания (из краткой выборки, которую я сделал). –
Вы хотите скачать источник из https://sourceforge.net/projects/jsch/files/jsch/jsch-0.1.42.zip/download и запустить «ant javadoc» –
Я пытался использовать JSch некоторое время назад и не может понять, как это так популярно. Он не предлагает абсолютно никакой документации (даже в пределах источника) и ужасного дизайна API (http://techtavern.wordpress.com/2008/09/30/about-jsch-open-source-project/) – rluba
Взгляните на недавно выпущенный SSHD, который основан на проекте Apache MINA.
Используя его, однако документации и примеров не хватает. –
Update: Проект GSOC и код там не активен, но это: https://github.com/hierynomus/sshj
hierynomus взял на себя в качестве сопровождающего с начала 2015 года Вот это старше, больше не поддерживается, Github ссылка:
https://github.com/shikhar/sshj
был проект GSOC:
http://code.google.com/p/commons-net-ssh/
Качество кода, кажется, лучше, чем JSch, что, хотя полная и рабочая реализация, не имеет документации. На странице Project отображается предстоящая бета-версия, последняя фиксация в репозитории была в середине августа.
Сравнить API:
http://code.google.com/p/commons-net-ssh/
SSHClient ssh = new SSHClient();
//ssh.useCompression();
ssh.loadKnownHosts();
ssh.connect("localhost");
try {
ssh.authPublickey(System.getProperty("user.name"));
new SCPDownloadClient(ssh).copy("ten", "/tmp");
} finally {
ssh.disconnect();
}
Session session = null;
Channel channel = null;
try {
JSch jsch = new JSch();
session = jsch.getSession(username, host, 22);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(password);
session.connect();
// exec 'scp -f rfile' remotely
String command = "scp -f " + remoteFilename;
channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
// get I/O streams for remote scp
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
channel.connect();
byte[] buf = new byte[1024];
// send '\0'
buf[0] = 0;
out.write(buf, 0, 1);
out.flush();
while (true) {
int c = checkAck(in);
if (c != 'C') {
break;
}
// read '0644 '
in.read(buf, 0, 5);
long filesize = 0L;
while (true) {
if (in.read(buf, 0, 1) < 0) {
// error
break;
}
if (buf[0] == ' ') {
break;
}
filesize = filesize * 10L + (long) (buf[0] - '0');
}
String file = null;
for (int i = 0;; i++) {
in.read(buf, i, 1);
if (buf[i] == (byte) 0x0a) {
file = new String(buf, 0, i);
break;
}
}
// send '\0'
buf[0] = 0;
out.write(buf, 0, 1);
out.flush();
// read a content of lfile
FileOutputStream fos = null;
fos = new FileOutputStream(localFilename);
int foo;
while (true) {
if (buf.length < filesize) {
foo = buf.length;
} else {
foo = (int) filesize;
}
foo = in.read(buf, 0, foo);
if (foo < 0) {
// error
break;
}
fos.write(buf, 0, foo);
filesize -= foo;
if (filesize == 0L) {
break;
}
}
fos.close();
fos = null;
if (checkAck(in) != 0) {
System.exit(0);
}
// send '\0'
buf[0] = 0;
out.write(buf, 0, 1);
out.flush();
channel.disconnect();
session.disconnect();
}
} catch (JSchException jsche) {
System.err.println(jsche.getLocalizedMessage());
} catch (IOException ioe) {
System.err.println(ioe.getLocalizedMessage());
} finally {
channel.disconnect();
session.disconnect();
}
}
Спасибо! Я использовал код Apache SSHD (который предлагает асинхронный API) как семя, которое дало проекту кикстарт. – shikhar
Отлично. Я начал проект с использованием JSch, но мне очень нравится переключаться, если я получаю больше положительных отзывов о commons-net-ssh. – miku
Я должен был упомянуть, что я был учеником GSOC :) – shikhar
Я только что обнаружил sshj, которая, кажется, гораздо более кратким API, чем JSch (но это требует Java 6). Документация в основном на примерах-в-репо на данный момент, и, как правило, этого достаточно для того, чтобы я смотрел в другом месте, но мне кажется достаточно хорошим, чтобы я мог сделать это в проекте, который только что начал.
SSHJ на самом деле работает кем-то из внешнего мира. JSCH - это плохой документ и дизайн API со скрытыми и в значительной степени неразборчивыми зависимостями. Если вы не хотите тратить много времени на прохождение кода, чтобы попытаться выяснить, что происходит, используйте SSHJ. (И мне жаль, что я не был суров или актуален об АОХ. Я действительно это делаю.) –
Да, sshj. Все, что я пробовал с ним работать: SCP, удаленное выполнение процессов, локальная и удаленная переадресация портов, агент-посредник с помощью [jsch-agent-proxy] (http://www.jcraft.com/jsch-agent-proxy). В АО был беспорядок. –
Существует новая версия Jsch up on github: https://github.com/vngx/vngx-jsch Некоторые из улучшений включают в себя: всесторонний javadoc, улучшенную производительность, улучшенную обработку исключений и лучшую привязку спецификации RFC. Если вы хотите каким-либо образом внести свой вклад, пожалуйста, откройте проблему или отправьте запрос на перенос.
Слишком плохо, что не было новой фиксации более 3 лет. –
Я принял ответ miku и пример кода jsch. Затем мне пришлось скачать несколько файлов во время сеанса и сохранить оригинальные отметки времени. Это мой пример кода, как это сделать, вероятно, многие люди считают это полезным. Пожалуйста, игнорируйте filenameHack() функцию своей собственной usecase.
package examples;
import com.jcraft.jsch.*;
import java.io.*;
import java.util.*;
public class ScpFrom2 {
public static void main(String[] args) throws Exception {
Map<String,String> params = parseParams(args);
if (params.isEmpty()) {
System.err.println("usage: java ScpFrom2 "
+ " user=myid password=mypwd"
+ " host=myhost.com port=22"
+ " encoding=<ISO-8859-1,UTF-8,...>"
+ " \"remotefile1=/some/file.png\""
+ " \"localfile1=file.png\""
+ " \"remotefile2=/other/file.txt\""
+ " \"localfile2=file.txt\""
);
return;
}
// default values
if (params.get("port") == null)
params.put("port", "22");
if (params.get("encoding") == null)
params.put("encoding", "ISO-8859-1"); //"UTF-8"
Session session = null;
try {
JSch jsch=new JSch();
session=jsch.getSession(
params.get("user"), // myuserid
params.get("host"), // my.server.com
Integer.parseInt(params.get("port")) // 22
);
session.setPassword(params.get("password"));
session.setConfig("StrictHostKeyChecking", "no"); // do not prompt for server signature
session.connect();
// this is exec command and string reply encoding
String encoding = params.get("encoding");
int fileIdx=0;
while(true) {
fileIdx++;
String remoteFile = params.get("remotefile"+fileIdx);
String localFile = params.get("localfile"+fileIdx);
if (remoteFile == null || remoteFile.equals("")
|| localFile == null || localFile.equals(""))
break;
remoteFile = filenameHack(remoteFile);
localFile = filenameHack(localFile);
try {
downloadFile(session, remoteFile, localFile, encoding);
} catch (Exception ex) {
ex.printStackTrace();
}
}
} catch(Exception ex) {
ex.printStackTrace();
} finally {
try{ session.disconnect(); } catch(Exception ex){}
}
}
private static void downloadFile(Session session,
String remoteFile, String localFile, String encoding) throws Exception {
// send exec command: scp -p -f "/some/file.png"
// -p = read file timestamps
// -f = From remote to local
String command = String.format("scp -p -f \"%s\"", remoteFile);
System.console().printf("send command: %s%n", command);
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command.getBytes(encoding));
// get I/O streams for remote scp
byte[] buf=new byte[32*1024];
OutputStream out=channel.getOutputStream();
InputStream in=channel.getInputStream();
channel.connect();
buf[0]=0; out.write(buf, 0, 1); out.flush(); // send '\0'
// reply: T<mtime> 0 <atime> 0\n
// times are in seconds, since 1970-01-01 00:00:00 UTC
int c=checkAck(in);
if(c!='T')
throw new IOException("Invalid timestamp reply from server");
long tsModified = -1; // millis
for(int idx=0; ; idx++){
in.read(buf, idx, 1);
if(tsModified < 0 && buf[idx]==' ') {
tsModified = Long.parseLong(new String(buf, 0, idx))*1000;
} else if(buf[idx]=='\n') {
break;
}
}
buf[0]=0; out.write(buf, 0, 1); out.flush(); // send '\0'
// reply: C0644 <binary length> <filename>\n
// length is given as a text "621873" bytes
c=checkAck(in);
if(c!='C')
throw new IOException("Invalid filename reply from server");
in.read(buf, 0, 5); // read '0644 ' bytes
long filesize=-1;
for(int idx=0; ; idx++){
in.read(buf, idx, 1);
if(buf[idx]==' ') {
filesize = Long.parseLong(new String(buf, 0, idx));
break;
}
}
// read remote filename
String origFilename=null;
for(int idx=0; ; idx++){
in.read(buf, idx, 1);
if(buf[idx]=='\n') {
origFilename=new String(buf, 0, idx, encoding); // UTF-8, ISO-8859-1
break;
}
}
System.console().printf("size=%d, modified=%d, filename=%s%n"
, filesize, tsModified, origFilename);
buf[0]=0; out.write(buf, 0, 1); out.flush(); // send '\0'
// read binary data, write to local file
FileOutputStream fos = null;
try {
File file = new File(localFile);
fos = new FileOutputStream(file);
while(filesize > 0) {
int read = Math.min(buf.length, (int)filesize);
read=in.read(buf, 0, read);
if(read < 0)
throw new IOException("Reading data failed");
fos.write(buf, 0, read);
filesize -= read;
}
fos.close(); // we must close file before updating timestamp
fos = null;
if (tsModified > 0)
file.setLastModified(tsModified);
} finally {
try{ if (fos!=null) fos.close(); } catch(Exception ex){}
}
if(checkAck(in) != 0)
return;
buf[0]=0; out.write(buf, 0, 1); out.flush(); // send '\0'
System.out.println("Binary data read");
}
private static int checkAck(InputStream in) throws IOException {
// b may be 0 for success
// 1 for error,
// 2 for fatal error,
// -1
int b=in.read();
if(b==0) return b;
else if(b==-1) return b;
if(b==1 || b==2) {
StringBuilder sb=new StringBuilder();
int c;
do {
c=in.read();
sb.append((char)c);
} while(c!='\n');
throw new IOException(sb.toString());
}
return b;
}
/**
* Parse key=value pairs to hashmap.
* @param args
* @return
*/
private static Map<String,String> parseParams(String[] args) throws Exception {
Map<String,String> params = new HashMap<String,String>();
for(String keyval : args) {
int idx = keyval.indexOf('=');
params.put(
keyval.substring(0, idx),
keyval.substring(idx+1)
);
}
return params;
}
private static String filenameHack(String filename) {
// It's difficult reliably pass unicode input parameters
// from Java dos command line.
// This dirty hack is my very own test use case.
if (filename.contains("${filename1}"))
filename = filename.replace("${filename1}", "Korilla ABC ÅÄÖ.txt");
else if (filename.contains("${filename2}"))
filename = filename.replace("${filename2}", "test2 ABC ÅÄÖ.txt");
return filename;
}
}
Вы могли повторно использовать сеанс и избегать накладных расходов на подключение/отключение? –
http://code.google.com/p/connectbot/, Компиляция SRC \ COM \ trilead \ ssh2 на Windows Linux или Android, это может создать локальный порт форвардер или создать динамический порт Экспедитор или другой еще
- 1. Java-приложение для Java для многих объектов
- 2. Java библиотека для Java для преобразования ЭОДА
- 3. Java Keylogger для телефонов Java
- 4. Bubblesort Java, новый для Java
- 5. Java - NoClassDefinitionFoundError для Java Класс
- 6. Наследование Java (новое для Java)
- 7. Список корзин для Java Java
- 8. Java для JRuby для Resque
- 9. Java для «forEach» для Scala
- 10. IDLE для Python для Java
- 11. C# для Java для android
- 12. для цикла для рекурсии JAVA
- 13. Java Тип Mapping для Java Native Access
- 14. Приложения для Android + Java модуль (Java 1.8)
- 15. Запись непрерывной петли для java в java
- 16. java.lang.OutOfMemoryError: Java куча пространства для Java 8
- 17. Спарк пример Java 7 для Java 8
- 18. Java: метод prune для связанного списка Java
- 19. Есть ли версия языка Java для Java?
- 20. Java Security Exception для Java AST
- 21. Настройка Syntastic для разработки Java Java
- 22. Разработка java-программы для компиляции .java-файлов
- 23. Java-адаптер Java MobileFirst для WS SOAP
- 24. Java-код для переименования пакетов Java
- 25. Java-приложение для администрирования Java-приложений?
- 26. EvoSuite поддержка Java для Java 7?
- 27. Java Desktop-App для Java-Web-App
- 28. Типы Java для Java Типы SQL Util
- 29. Общие параметры Java для зависимых типов Java
- 30. Selenium java для вызова функции java-скрипта
я имел обыкновение использовать Trilead SSH, но когда я проверил сайт сегодня кажется, что они отказываются от него. :(Это был мой абсолютный фаворит. –
Кстати, похоже, что Trilead SSH2 активно поддерживается (в октябре 2013 года): [https://github.com/jenkinsci/trilead-ssh2] –
Попробуйте [jcabi-ssh] (http://ssh.jcabi.com), это объясняется здесь http://www.yegor256.com/2014/09/02/java-ssh-client.html – yegor256