如何使用 JSch 打开一个会话,关闭该会话,然后使用相同的凭据打开一个新会话?
How do I open a session using JSch, close that session, and then open a new one using the same credentials?
我无法使用 JSch 获取会话,关闭该会话,然后在一段时间后使用相同的凭据打开一个新会话。有人可以看看我下面的解释并提供任何建议吗?非常感谢。
我不确定我的问题是我的测试设置还是我的代码,但我遇到的问题是我无法打开、关闭,然后使用具有相同凭据的 JSch 打开新的 ssh 会话。我的测试 class 包含两个测试,这两个测试都测试下面的生产代码:
def transferFiles(String filePath, Closure fileAction) {
def secureChannel = new JSch()
def session = secureChannel.getSession(sftpUser, sftpHost, sftpPort)
session.setConfig('StrictHostKeyChecking', 'no')
session.password = sftpPass
session.connect()
try {
def sftpChannel = (ChannelSftp) session.openChannel('sftp')
sftpChannel.connect()
try {
processFiles(sftpChannel, filePath, fileAction)
} finally {
sftpChannel.exit()
}
} finally {
session.disconnect()
}
}
如果我只 运行 一个测试,那么它总是会通过,但是如果我一次 运行 整个规范,那么无论哪个测试 运行 都会通过,无论哪个第二次测试 运行s 将始终失败,但出现以下异常:
com.jcraft.jsch.JSchException: java.net.ConnectException: Connection refused
at com.jcraft.jsch.Util.createSocket(Util.java:349)
at com.jcraft.jsch.Session.connect(Session.java:215)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.simplify.acquirer.evo.service.FileTransferringService.transferFiles(FileTransferringService.groovy:32)
at com.simplify.acquirer.evo.service.DepositService.processDeposits(DepositService.groovy:8)
at com.simplify.acquirer.evo.service.FileProcessingIntegrationSpec.Deposits are successfully processed(FileProcessingIntegrationSpec.groovy:127)
Caused by: java.net.ConnectException: Connection refused
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 java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at com.jcraft.jsch.Util.createSocket(Util.java:343)
... 5 more
这是我的测试设置(从测试中删除了 then 块,因为它们不应该相关):
import com.jcraft.jsch.ChannelSftp
import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session
import com.jcraft.jsch.UserInfo
import org.apache.sshd.SshServer
import org.apache.sshd.server.Command
import org.apache.sshd.server.CommandFactory
import org.apache.sshd.server.PasswordAuthenticator
import org.apache.sshd.server.command.ScpCommandFactory
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
import org.apache.sshd.server.session.ServerSession
import org.apache.sshd.server.sftp.SftpSubsystem
import spock.lang.Shared
import spock.lang.Specification
class FileProcessingIntegrationSpec extends Specification {
@Shared
SshServer sshd
def setupSpec() {
FileTransferringService.sftpUser = 'remote-username'
FileTransferringService.sftpPass = 'remote-password'
FileTransferringService.sftpHost = 'localhost'
FileTransferringService.sftpPort = 22999
sshd = SshServer.setUpDefaultServer()
sshd.port = FileTransferringService.sftpPort
sshd.keyPairProvider = new SimpleGeneratorHostKeyProvider('hostkey.ser')
sshd.passwordAuthenticator = new PasswordAuthenticator() {
public boolean authenticate(String username, String password, ServerSession session) {
true
}
}
sshd.commandFactory = new ScpCommandFactory(new CommandFactory() {
public Command createCommand(String command) {
System.out.println("Command: $command")
null
}
})
sshd.subsystemFactories = [new SftpSubsystem.Factory()]
sshd.start()
JSch sch = new JSch();
Session session = sch.getSession("sshd", FileTransferringService.sftpHost, FileTransferringService.sftpPort);
session.userInfo = new UserInfo() {
public String getPassphrase() {
null
}
public String getPassword() {
'sshd'
}
public boolean promptPassword(String message) {
true
}
public boolean promptPassphrase(String message) {
false
}
public boolean promptYesNo(String message) {
true
}
public void showMessage(String message) {
}
}
session.connect()
ChannelSftp c = (ChannelSftp) session.openChannel("sftp")
c.connect()
c.put(new FileInputStream('src/integrationTest/resources/file1.xls'), 'file1.xls')
c.put(new FileInputStream('src/integrationTest/resources/file2.csv'), 'file2.csv')
c.disconnect()
}
def cleanup() {
sshd.stop()
}
def "Files are successfully processed"() {
when:
def result = new FileProcessingService().processFile('file1.xls')
then:
...
}
def "More files are successfully processed"() {
when:
def result = new FileProcessingService().processFile('file2.csv')
then:
...
}
}
如果需要更多信息,我会尽力提供。再次感谢。
您需要使用 cleanupSpec
而不是 cleanup
。您的代码现在的工作方式是,您在 setupSpec
中创建的 sshd 服务器在第一次测试后停止,这解释了为什么第二次测试随后失败。
这可能只是一个疏忽,但为了完整起见,这里是夹具方法定义:
def setup() {} // run before every feature method
def cleanup() {} // run after every feature method
def setupSpec() {} // run before the first feature method
def cleanupSpec() {} // run after the last feature method
我无法使用 JSch 获取会话,关闭该会话,然后在一段时间后使用相同的凭据打开一个新会话。有人可以看看我下面的解释并提供任何建议吗?非常感谢。
我不确定我的问题是我的测试设置还是我的代码,但我遇到的问题是我无法打开、关闭,然后使用具有相同凭据的 JSch 打开新的 ssh 会话。我的测试 class 包含两个测试,这两个测试都测试下面的生产代码:
def transferFiles(String filePath, Closure fileAction) {
def secureChannel = new JSch()
def session = secureChannel.getSession(sftpUser, sftpHost, sftpPort)
session.setConfig('StrictHostKeyChecking', 'no')
session.password = sftpPass
session.connect()
try {
def sftpChannel = (ChannelSftp) session.openChannel('sftp')
sftpChannel.connect()
try {
processFiles(sftpChannel, filePath, fileAction)
} finally {
sftpChannel.exit()
}
} finally {
session.disconnect()
}
}
如果我只 运行 一个测试,那么它总是会通过,但是如果我一次 运行 整个规范,那么无论哪个测试 运行 都会通过,无论哪个第二次测试 运行s 将始终失败,但出现以下异常:
com.jcraft.jsch.JSchException: java.net.ConnectException: Connection refused
at com.jcraft.jsch.Util.createSocket(Util.java:349)
at com.jcraft.jsch.Session.connect(Session.java:215)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.simplify.acquirer.evo.service.FileTransferringService.transferFiles(FileTransferringService.groovy:32)
at com.simplify.acquirer.evo.service.DepositService.processDeposits(DepositService.groovy:8)
at com.simplify.acquirer.evo.service.FileProcessingIntegrationSpec.Deposits are successfully processed(FileProcessingIntegrationSpec.groovy:127)
Caused by: java.net.ConnectException: Connection refused
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 java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at com.jcraft.jsch.Util.createSocket(Util.java:343)
... 5 more
这是我的测试设置(从测试中删除了 then 块,因为它们不应该相关):
import com.jcraft.jsch.ChannelSftp
import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session
import com.jcraft.jsch.UserInfo
import org.apache.sshd.SshServer
import org.apache.sshd.server.Command
import org.apache.sshd.server.CommandFactory
import org.apache.sshd.server.PasswordAuthenticator
import org.apache.sshd.server.command.ScpCommandFactory
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
import org.apache.sshd.server.session.ServerSession
import org.apache.sshd.server.sftp.SftpSubsystem
import spock.lang.Shared
import spock.lang.Specification
class FileProcessingIntegrationSpec extends Specification {
@Shared
SshServer sshd
def setupSpec() {
FileTransferringService.sftpUser = 'remote-username'
FileTransferringService.sftpPass = 'remote-password'
FileTransferringService.sftpHost = 'localhost'
FileTransferringService.sftpPort = 22999
sshd = SshServer.setUpDefaultServer()
sshd.port = FileTransferringService.sftpPort
sshd.keyPairProvider = new SimpleGeneratorHostKeyProvider('hostkey.ser')
sshd.passwordAuthenticator = new PasswordAuthenticator() {
public boolean authenticate(String username, String password, ServerSession session) {
true
}
}
sshd.commandFactory = new ScpCommandFactory(new CommandFactory() {
public Command createCommand(String command) {
System.out.println("Command: $command")
null
}
})
sshd.subsystemFactories = [new SftpSubsystem.Factory()]
sshd.start()
JSch sch = new JSch();
Session session = sch.getSession("sshd", FileTransferringService.sftpHost, FileTransferringService.sftpPort);
session.userInfo = new UserInfo() {
public String getPassphrase() {
null
}
public String getPassword() {
'sshd'
}
public boolean promptPassword(String message) {
true
}
public boolean promptPassphrase(String message) {
false
}
public boolean promptYesNo(String message) {
true
}
public void showMessage(String message) {
}
}
session.connect()
ChannelSftp c = (ChannelSftp) session.openChannel("sftp")
c.connect()
c.put(new FileInputStream('src/integrationTest/resources/file1.xls'), 'file1.xls')
c.put(new FileInputStream('src/integrationTest/resources/file2.csv'), 'file2.csv')
c.disconnect()
}
def cleanup() {
sshd.stop()
}
def "Files are successfully processed"() {
when:
def result = new FileProcessingService().processFile('file1.xls')
then:
...
}
def "More files are successfully processed"() {
when:
def result = new FileProcessingService().processFile('file2.csv')
then:
...
}
}
如果需要更多信息,我会尽力提供。再次感谢。
您需要使用 cleanupSpec
而不是 cleanup
。您的代码现在的工作方式是,您在 setupSpec
中创建的 sshd 服务器在第一次测试后停止,这解释了为什么第二次测试随后失败。
这可能只是一个疏忽,但为了完整起见,这里是夹具方法定义:
def setup() {} // run before every feature method
def cleanup() {} // run after every feature method
def setupSpec() {} // run before the first feature method
def cleanupSpec() {} // run after the last feature method