2016-03-31 3 views
0

Я настроил Apache FtpServer следующим образом:«BindException: Адрес уже используется» в Spring с Apache FtpServer

@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(); 
} 

Обратите внимание, что сервер автоматически запускается в @PostConstruct. У меня разные тесты, сконфигурированные в SpringBoot следующим образом:

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

Когда я запускаю тесты индивидуально, они преуспевают. Однако, когда я запускаю их вместе, я получаю java.net.BindException: Address already in use: bind. Как я могу избежать этого?

+0

Какова область вашей FtpDummyServer? Я думаю, что вы многократно вводите FtpDummyServer в свой тест, если попытаетесь поделиться одним FtpDummyServer для всех тестовых случаев. –

+0

У FtpDummyServer есть аннотация @Component. Это singleton per dfault. –

+0

можете ли вы разместить свои тестовые примеры? –

ответ

2

Для каждого теста создается FtpDummyServer. Однако @PreDestroy так и не был вызван. @DirtiesContext решает проблему.

2

Если вы посмотрите на исключение stacktrace, вы увидите, какой адрес пытается использовать FTP-сервер. Smth как

причиненном: org.apache.ftpserver.FtpServerConfigurationException: Не удалось привязать к решению 0.0.0.0/0.0.0.0:21, проверьте конфигурацию

Это может произойти из-за:

  1. Другой экземпляр вашего приложения использует адрес. Если это так, вам нужно их прекратить.
  2. В некоторых других процессах используется адрес/порт. В этом случае вы можете перенастроить ftp-сервер для привязки к другому адресу.

    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(); 
    

Используйте NetStat, чтобы выяснить, идентификатор процесса, который содержит адрес.

+0

Для каждого теста создается FtpDummyServer. Однако '@ PreDestroy' никогда не назывался. '@ DirtiesContext' решает проблему. –

+0

@ RenéWinkler Я как-то пропустил, что это был тест – Evgeny

0

Использование @DirtiesContext с @TestExecutionListeners работает, но не забудьте объединить свой контекст со стандартными. например:

@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 { 
... 
} 

Посмотрите там: Does Spring @DirtiesContext reload Spring context?

Смежные вопросы