Home > Back-end >  Start ActiveMQ broker before Application
Start ActiveMQ broker before Application

Time:12-16

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
  • Related