3

I have been recreating this example in my local: https://github.com/spring-projects/spring-integration-samples/tree/master/basic/sftp

But this time using just annotations instead xml config. I have something like this:

@Configuration
public class SftpExampleBeanClasses extends SftpConfig {

@Bean
public CachingSessionFactory<LsEntry> sftpSessionFactory() throws IOException {
    DefaultSftpSessionFactory sftpSessionFactory = new DefaultSftpSessionFactory();
    sftpSessionFactory.setHost(this.host);
    sftpSessionFactory.setPort(this.port);
    sftpSessionFactory.setUser(this.username);
    InputStream stream = new ClassPathResource(this.privatekey).getInputStream();
    sftpSessionFactory.setPrivateKey(new ByteArrayResource(StreamUtils.copyToByteArray(stream)));
    sftpSessionFactory.setPrivateKeyPassphrase(this.passphrase);
    sftpSessionFactory.setAllowUnknownKeys(true);
    return new CachingSessionFactory<LsEntry>(sftpSessionFactory);

    //return sftpSessionFactory;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
@Bean
@ServiceActivator(inputChannel = "ftpChannel", adviceChain = "retryAdvice")
public MessageHandler ftpHandler() throws IOException {
    FileTransferringMessageHandler handler = new FileTransferringMessageHandler(this.sftpSessionFactory());
    handler.setRemoteDirectoryExpression(new LiteralExpression("/"));
    return handler;
}

}

SftpCommon class:

@Configuration
public class SftpCommon extends SftpConfig {

    @Bean
    public int serverPort(){
        if(this.port == -1){
            return EmbeddedSftpServer.PORT;
        }
        return this.port;
    }

    @Bean
    public EmbeddedSftpServer embeddedSftpServer(){
         EmbeddedSftpServer embeddedSftpServer = new EmbeddedSftpServer();
         embeddedSftpServer.setPort(serverPort());
         return embeddedSftpServer;
    }   
}

SftpConfig Class:

@Configuration
@PropertySource(value="classpath:user.properties")
public class SftpConfig {

    @Value("${port}")
    protected
    int port;

    @Value("${username}")
    protected
    String username;

    @Value("${passphrase}")
    protected
    String passphrase;

    @Value("${host}")
    protected
    String host;

    @Value("${private.keyfile}")
    protected
    String  privatekey;

    public String getHost() {
        return host;
    }

    @Bean
    public String getUsername() {
        return this.username;
    }

    @Bean
    public String getPassphrase() {
        return this.passphrase;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public String getPrivatekey() {
        return privatekey;
    }
}

And in my test I have something like this:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes ={SftpExampleBeanClasses.class,SftpCommon.class, SftpConfig.class})
    public class SftpOutboundTransferSample {

    @Autowired
    ApplicationContext applicationContext;

    @Test
    public void testOutbound() throws Exception{

        final String sourceFileName = "README.md";
        final String destinationFileName = sourceFileName +"_foo";

        @SuppressWarnings("unchecked")
        SessionFactory<LsEntry> sessionFactory = (SessionFactory<LsEntry>)


        applicationContext.getBean(CachingSessionFactory.class);
        /* this is the line where I'm getting issues */
        sessionFactory.getSession();
    }

My stackTrace is this one:

org.springframework.messaging.MessagingException: Failed to obtain pooled item; nested exception is java.lang.IllegalStateException: failed to create SFTP Session at org.springframework.integration.util.SimplePool.getItem(SimplePool.java:178) at org.springframework.integration.file.remote.session.CachingSessionFactory.getSession(CachingSessionFactory.java:123) at com.spring.example.sftp.SftpOutboundTransferSample.testOutbound(SftpOutboundTransferSample.java:62) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.IllegalStateException: failed to create SFTP Session at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:393) at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:57) at org.springframework.integration.file.remote.session.CachingSessionFactory$1.createForPool(CachingSessionFactory.java:81) at org.springframework.integration.file.remote.session.CachingSessionFactory$1.createForPool(CachingSessionFactory.java:78) at org.springframework.integration.util.SimplePool.doGetItem(SimplePool.java:188) at org.springframework.integration.util.SimplePool.getItem(SimplePool.java:169) ... 31 more Caused by: java.lang.IllegalStateException: failed to connect at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:273) at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:388) ... 36 more Caused by: com.jcraft.jsch.JSchException: Packet corrupt Ma at com.jcraft.jsch.Session.start_discard(Session.java:1067) at com.jcraft.jsch.Session.read(Session.java:937) at com.jcraft.jsch.Session.connect(Session.java:309) at com.jcraft.jsch.Session.connect(Session.java:183) at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:264) ... 37 more

I have been searched on Internet, but to be honest, I don't undestand why I'm getting this exception:

com.jcraft.jsch.JSchException: Packet corrupt

My log4j.xml config:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <!-- Appenders -->
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n" />
        </layout>
    </appender>

    <!-- Loggers -->
    <logger name="org.springframework.integration">
        <level value="warn" />
    </logger>

    <logger name="org.springframework.integration.samples">
        <level value="info" />
    </logger>

    <logger name="log4j.category.com.jcraft.jsch">
        <level value="debug" />
        <appender-ref ref="console" />
    </logger>

    <!-- Root Logger -->
    <root>
        <priority value="debug" />
        <appender-ref ref="console" />
    </root>

</log4j:configuration>

[UPDATED] FULL ECLIPSE'S OUTPUT (CONSOLE) HERE: https://gist.github.com/columb1a/fe2d4dccabb6a5d9cecd3225d2a591dc

Columb1a
  • 463
  • 2
  • 11
  • 25

1 Answers1

2

I solved my issue:

In my *.properties file the port number of the server is -1. Then the server tries to start, if it is able to find a port (random port) other than -1, then it starts automatically. Then I have to inject that random port number in my SFTP session. The point is, I was using the "-1" value (declared in my *.properties file) in my sftp session, instead of using the random value that was generated by the server. Then my session was not able to connect to the server.

Points to considered:

  • In this case, unfortunately, the "debug" level for jsch was not useful.
  • The Stack trace was the "hint" since somehow, if you are not able to connect, then, that could means your are using the wrong parameters to connect (maybe). Therefore at least in my case, I was using the wrong port number in my session.
Columb1a
  • 463
  • 2
  • 11
  • 25