My application creates connections to the embedded ActiveMQ Artemis broker during application start, so the broker must exist before application starts.
I've created an embedded broker with the Holder pattern:
public final class EmbeddedActiveMQHolder {
private EmbeddedActiveMQHolder() {
super();
}
private static final EmbeddedActiveMQ embeddedActiveMQ = new EmbeddedActiveMQ();
@SneakyThrows
public static EmbeddedActiveMQ getEmbeddedActiveMQ() {
if (embeddedActiveMQ.getActiveMQServer() == null) {
Configuration configuration = new ConfigurationImpl();
configuration.addAcceptorConfiguration("in-vm", "vm://0");
configuration.setPersistenceEnabled(false);
configuration.setSecurityEnabled(false);
configuration.setCreateJournalDir(false);
configuration.setCreateBindingsDir(false);
embeddedActiveMQ.setConfiguration(configuration);
embeddedActiveMQ.start();
}
return embeddedActiveMQ;
}
}
Than I've created a test configuration:
@TestConfiguration
public class ArtemisTestConfiguration {
@PostConstruct
@EventListener(ApplicationReadyEvent.class)
public EmbeddedActiveMQ embeddedArtemis() throws Exception {
System.out.println("ActiveMQ starting!");
return EmbeddedActiveMQHolder.getEmbeddedActiveMQ();
}
}
And then I've attached it to my base test class:
@SpringBootTest(classes = {Application.class})
@TestPropertySource(properties = {
"activemq.broker.url=vm://0?reconnectAttempts=3",
})
@ContextConfiguration(classes = ArtemisTestConfiguration.class)
public abstract class BaseTest {
}
But the broker does not start and the message "ActiveMQ starting!" does not appear in the terminal, and the service returns an error:
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'containerFactory': Invocation of init method failed; nested exception is javax.jms.JMSException: Failed to create session factory
...
Caused by: javax.jms.JMSException: Failed to create session factory
...
Caused by: ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.]
...
What am I doing wrong?
CodePudding user response:
ApplicationContextInitializer helped me to solve this problem! https://www.logicbig.com/tutorials/spring-framework/spring-core/tests-context-initializer.html
I've created an implementation of initializer interface and moved broker there:
public class ArtemisTestContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
EmbeddedActiveMQHolder.getEmbeddedActiveMQ();
}
}
And then I've deleted broker from my ArtemisTestConfiguration class:
@TestConfiguration
public class ArtemisTestConfiguration {
@MockBean
ArtemisContinualConsumer artemisContinualConsumer;
@Bean
public JmsTemplate artemisJmsTemplate() {
return new JmsTemplate(artemisTestConnectionFactory());
}
@Bean
public ConnectionFactory artemisTestConnectionFactory() {
return new ActiveMQConnectionFactory("vm://0");
}
}
In the end I've added initializer to the @ContextConfiguration annotation:
@SpringBootTest(classes = {Application.class})
@TestPropertySource(properties = {
"activemq.broker.url=vm://0?reconnectAttempts=3",
})
@ContextConfiguration(classes = ArtemisTestConfiguration.class,
initializers = ArtemisTestContextInitializer.class)
public abstract class BaseTest {
}
Now the broker starts before the application:
2022-12-13 13:58:19,742 INFO o.a.a.a.c.server.: : AMQ221007: Server is now live
2022-12-13 13:58:22,474 INFO o.s.b.w.s.c.ServletWebServerApplicationContext.: : Root WebApplicationContext: initialization completed in 2696 ms