JSch SFTP 放入 IBM z/OS 失败:无法写入文件;嵌套异常是 3:权限被拒绝
JSch SFTP put to IBM z/OS fails :failed to write file; nested exception is 3: Permission denied
我正在尝试使用 JSch 通过 SFTP 将文件放入大型机。
代码如下:
public void uploadFile(String contents) throws Exception {
JSch.setLogger(new JSCHLogger());
connectIfDisconected();
LOGGER.info("Channel isConnected=: " + channel.isConnected());
OutputStream os = channel.put("//!DTS4.UP.G5TB4.S60301");
os.write(contents.getBytes());
os.flush();
os.close();
}
protected void connectIfDisconected() throws JSchException {
if (!session.isConnected()) {
LOGGER.info(LogEvent.create(".connectIfDisconected()", "Reconnecting session and channel..."));
session.connect();
if (channel != null) {
channel.exit();
}
channel = (ChannelSftp) session.openChannel("sftp");
} else if (!channel.isConnected()) {
LOGGER.info(LogEvent.create(".connectIfDisconected()", "Reconnecting channel..."));
channel.connect();
}
}
这是会话配置:
session = jsch.getSession(username, host, port);
Properties config = getProperties(host, port);
session.setConfig(config);
...
...
protected Properties getProperties(String host, int port) throws JSchException {
Properties config = new Properties();
config.put("StrictHostKeyChecking", strictHostChecking ? "yes" : "no");
config.put("kex", "diffie-hellman-group-exchange-sha1");
config.put("PreferredAuthentications", "password");
return config;
}
会话连接正常!
当我尝试放置文件时,我在行中遇到以下异常
OutputStream os = channel.put(targetFile);
com.three60t.tex.app.exceptions.business.BusinessException: Error while delivering to Client communicator : Permission denied
at com.three60t.integration.posttrade.utils.DefaultReporter.reportError(DefaultReporter.java:68)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.reportError(InternalTransformationService.java:439)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.deliver(InternalTransformationService.java:378)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.doDeliver(InternalTransformationService.java:314)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.transform(InternalTransformationService.java:305)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.three60t.tex.communication.message.handler.MessageDispatcher.dispatchToObject(MessageDispatcher.java:722)
at com.three60t.tex.communication.message.handler.MessageDispatcher.doExecuteObject(MessageDispatcher.java:543)
at com.three60t.tex.communication.message.handler.MessageDispatcher.access0(MessageDispatcher.java:77)
at com.three60t.tex.communication.message.handler.MessageDispatcher.run(MessageDispatcher.java:264)
at com.three60t.tex.communication.message.handler.MessageDispatcher.run(MessageDispatcher.java:444)
at com.three60t.concurrent.executor.v2.RunnableWithTimings.run(RunnableWithTimings.java:81)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: 3: Permission denied
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:753)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:700)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:694)
at com.three60t.integration.tradeimporters.sftp.DtccSftpClient.uploadFile(DtccSftpClient.java:34)
at com.three60t.integration.tradeimporters.sftp.SFTPTransportDtcc.upload(SFTPTransportDtcc.java:41)
at com.three60t.framework.communication.integration.SFTPTransport.upload(SFTPTransport.java:148)
at com.three60t.integration.tradeimporters.sftp.SFTPTransportDtcc.upload(SFTPTransportDtcc.java:25)
at com.three60t.integration.tradeimporters.sftp.SFTPTransportDtcc.deliver(SFTPTransportDtcc.java:55)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.deliver(InternalTransformationService.java:362)
... 15 more
当我使用终端尝试同样的操作时,一切正常!
sftp XXXX@fdmoverspse.dtcc.com
Connecting to fdmoverspse.dtcc.com...
XXXX@fdmoverspse.dtcc.com's password:
sftp> put myfile.xml //!DTS4.UP.G5TB4.S60301
Uploading myfile.xml to //!DTS4.UP.G5TB4.S60301
myfile.xml 100% 7901 7.7KB/s 00:00
sftp>
有什么解决办法吗?
如果路径以两个斜杠开头,ChannelSftp.glob_remote
中有一个 "bug" 会去掉第二个斜杠。
而不是这个:
if(!pattern_has_wildcard){
if(!dir.equals("/"))
dir+="/";
v.addElement(dir+Util.unquote(_pattern));
return v;
}
代码应该是这样的:
if(!pattern_has_wildcard){
if(foo != 0)
dir+="/";
v.addElement(dir+Util.unquote(_pattern));
return v;
}
我能够使用 sshj 放置文件。有一个简单的客户端适合我:
public class DtccSftpSshjClient {
private static final Logger LOGGER = Log.getLogger(DtccSftpSshjClient.class);
private String hostname;
private String username;
private String password;
private SSHClient client;
public DtccSftpSshjClient(String hostname, String username, String password) throws IOException {
this.hostname = hostname;
this.username = username;
this.password = password;
client = new SSHClient();
client.addHostKeyVerifier(new PromiscuousVerifier());
client.connect(hostname);
client.authPassword(username, password);
}
public void upload(String refId, String message, String dest) {
try {
LocalSourceFile messageFile = new InMemoryTradeFile(message, refId);
SFTPClient sftp = client.newSFTPClient();
sftp.put(messageFile, dest);
sftp.close();
} catch (Exception e) {
LOGGER.error(e.toString());
}
}
public void closeConnection() throws IOException {
client.disconnect();
}
private class InMemoryTradeFile extends InMemorySourceFile {
String message;
String refId;
public InMemoryTradeFile(String message, String refId) {
this.message = message;
this.refId = refId;
}
@Override
public String getName() {
return refId;
}
@Override
public long getLength() {
return message.getBytes().length;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(message.getBytes());
}
}
}
希望对您有所帮助。
我正在尝试使用 JSch 通过 SFTP 将文件放入大型机。
代码如下:
public void uploadFile(String contents) throws Exception {
JSch.setLogger(new JSCHLogger());
connectIfDisconected();
LOGGER.info("Channel isConnected=: " + channel.isConnected());
OutputStream os = channel.put("//!DTS4.UP.G5TB4.S60301");
os.write(contents.getBytes());
os.flush();
os.close();
}
protected void connectIfDisconected() throws JSchException {
if (!session.isConnected()) {
LOGGER.info(LogEvent.create(".connectIfDisconected()", "Reconnecting session and channel..."));
session.connect();
if (channel != null) {
channel.exit();
}
channel = (ChannelSftp) session.openChannel("sftp");
} else if (!channel.isConnected()) {
LOGGER.info(LogEvent.create(".connectIfDisconected()", "Reconnecting channel..."));
channel.connect();
}
}
这是会话配置:
session = jsch.getSession(username, host, port);
Properties config = getProperties(host, port);
session.setConfig(config);
...
...
protected Properties getProperties(String host, int port) throws JSchException {
Properties config = new Properties();
config.put("StrictHostKeyChecking", strictHostChecking ? "yes" : "no");
config.put("kex", "diffie-hellman-group-exchange-sha1");
config.put("PreferredAuthentications", "password");
return config;
}
会话连接正常!
当我尝试放置文件时,我在行中遇到以下异常
OutputStream os = channel.put(targetFile);
com.three60t.tex.app.exceptions.business.BusinessException: Error while delivering to Client communicator : Permission denied
at com.three60t.integration.posttrade.utils.DefaultReporter.reportError(DefaultReporter.java:68)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.reportError(InternalTransformationService.java:439)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.deliver(InternalTransformationService.java:378)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.doDeliver(InternalTransformationService.java:314)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.transform(InternalTransformationService.java:305)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.three60t.tex.communication.message.handler.MessageDispatcher.dispatchToObject(MessageDispatcher.java:722)
at com.three60t.tex.communication.message.handler.MessageDispatcher.doExecuteObject(MessageDispatcher.java:543)
at com.three60t.tex.communication.message.handler.MessageDispatcher.access0(MessageDispatcher.java:77)
at com.three60t.tex.communication.message.handler.MessageDispatcher.run(MessageDispatcher.java:264)
at com.three60t.tex.communication.message.handler.MessageDispatcher.run(MessageDispatcher.java:444)
at com.three60t.concurrent.executor.v2.RunnableWithTimings.run(RunnableWithTimings.java:81)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: 3: Permission denied
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:753)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:700)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:694)
at com.three60t.integration.tradeimporters.sftp.DtccSftpClient.uploadFile(DtccSftpClient.java:34)
at com.three60t.integration.tradeimporters.sftp.SFTPTransportDtcc.upload(SFTPTransportDtcc.java:41)
at com.three60t.framework.communication.integration.SFTPTransport.upload(SFTPTransport.java:148)
at com.three60t.integration.tradeimporters.sftp.SFTPTransportDtcc.upload(SFTPTransportDtcc.java:25)
at com.three60t.integration.tradeimporters.sftp.SFTPTransportDtcc.deliver(SFTPTransportDtcc.java:55)
at com.three60t.integration.posttrade.transformationService.InternalTransformationService.deliver(InternalTransformationService.java:362)
... 15 more
当我使用终端尝试同样的操作时,一切正常!
sftp XXXX@fdmoverspse.dtcc.com
Connecting to fdmoverspse.dtcc.com...
XXXX@fdmoverspse.dtcc.com's password:
sftp> put myfile.xml //!DTS4.UP.G5TB4.S60301
Uploading myfile.xml to //!DTS4.UP.G5TB4.S60301
myfile.xml 100% 7901 7.7KB/s 00:00
sftp>
有什么解决办法吗?
如果路径以两个斜杠开头,ChannelSftp.glob_remote
中有一个 "bug" 会去掉第二个斜杠。
而不是这个:
if(!pattern_has_wildcard){
if(!dir.equals("/"))
dir+="/";
v.addElement(dir+Util.unquote(_pattern));
return v;
}
代码应该是这样的:
if(!pattern_has_wildcard){
if(foo != 0)
dir+="/";
v.addElement(dir+Util.unquote(_pattern));
return v;
}
我能够使用 sshj 放置文件。有一个简单的客户端适合我:
public class DtccSftpSshjClient {
private static final Logger LOGGER = Log.getLogger(DtccSftpSshjClient.class);
private String hostname;
private String username;
private String password;
private SSHClient client;
public DtccSftpSshjClient(String hostname, String username, String password) throws IOException {
this.hostname = hostname;
this.username = username;
this.password = password;
client = new SSHClient();
client.addHostKeyVerifier(new PromiscuousVerifier());
client.connect(hostname);
client.authPassword(username, password);
}
public void upload(String refId, String message, String dest) {
try {
LocalSourceFile messageFile = new InMemoryTradeFile(message, refId);
SFTPClient sftp = client.newSFTPClient();
sftp.put(messageFile, dest);
sftp.close();
} catch (Exception e) {
LOGGER.error(e.toString());
}
}
public void closeConnection() throws IOException {
client.disconnect();
}
private class InMemoryTradeFile extends InMemorySourceFile {
String message;
String refId;
public InMemoryTradeFile(String message, String refId) {
this.message = message;
this.refId = refId;
}
@Override
public String getName() {
return refId;
}
@Override
public long getLength() {
return message.getBytes().length;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(message.getBytes());
}
}
}
希望对您有所帮助。