简体   繁体   中英

“BindException: Address already in use” in Spring with Apache FtpServer

I configured an Apache FtpServer as follows:

@Component
public class FtpDummyServer {

private FtpServer server;

@PostConstruct
public void init() throws FtpException {
    ..some initialization
    this.server = serverFactory.createServer();
    this.server.start();
}

@PreDestroy
public void stop() {
    this.server.stop();
}

Notice that the server is automatically started in the @PostConstruct. I have different tests configured in SpringBoot as follows:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MainApplication.class)
@WebIntegrationTest
public class ApplicationTestX {
...
}

When I run the tests individually, they succeed. However, when I run them together, I get a java.net.BindException: Address already in use: bind . How can I avoid that?

If you take a look at exception stacktrace you will see what address ftp server tries to use. Smth like

Caused by: org.apache.ftpserver.FtpServerConfigurationException: Failed to bind to address 0.0.0.0/0.0.0.0:21, check configuration

It may happen because:

  1. Another instance of your app uses address. If so you need to terminate them.
  2. Some other process uses address/port. In this case you can reconfigure ftp server to bind to another address.

     FtpServerFactory serverFactory = new FtpServerFactory(); ListenerFactory factory = new ListenerFactory(); factory.setPort(2222); //use alternative port instead of default 21 serverFactory.addListener("default", factory.createListener()); server = serverFactory.createServer(); server.start(); 

Use netstat to figure out process id that holds address.

For each test, an FtpDummyServer is created. However, @PreDestroy was never called. @DirtiesContext solves the problem.

Using @DirtiesContext with @TestExecutionListeners works but dont forget to merge your context with the default ones. Eg:

@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@TestExecutionListeners(value = {DirtiesContextTestExecutionListener.class}, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
@SpringApplicationConfiguration(classes = MainApplication.class)
@WebIntegrationTest
public class ApplicationTestX {
...
}

Have a look there: Does Spring @DirtiesContext reload Spring context?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM