3

I am learning JMS and different types of brokers out there. I am currently using ActiveMQ (Artemis) for a dummy project.

I currently have Artemis running on the default settings. I can go to the management console and see the queues and topics. I am now creating 2 Java Spring-based apps; one for producing and one for consuming. I have seen few tutorials out there, but I'm getting a NPE, which I'm not sure - why, as I believe I am autowiring the bean correctly.

These are my classes:

Main class:

@SpringBootApplication
public class SpringJmsApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringJmsApplication.class, args);

    SendMessage send = new SendMessage("This is the test message");
  }
}

Sender:

public class Sender {

  private static final Logger LOGGER =
      LoggerFactory.getLogger(Sender.class);

  @Autowired
  private JmsTemplate jmsTemplate;

  public void send(String message) {
    LOGGER.info("sending message='{}'", message);
    jmsTemplate.convertAndSend("helloworld.q", message);
  }
}

Sender Config:

@Configuration
public class SenderConfig {

  @Value("${artemis.broker-url}")
  private String brokerUrl;

  @Bean
  public ActiveMQConnectionFactory senderActiveMQConnectionFactory() {
    return new ActiveMQConnectionFactory(brokerUrl);
  }

  @Bean
  public CachingConnectionFactory cachingConnectionFactory() {
    return new CachingConnectionFactory(
        senderActiveMQConnectionFactory());
  }

  @Bean
  public JmsTemplate jmsTemplate() {
    return new JmsTemplate(cachingConnectionFactory());
  }

  @Bean
  public Sender sender() {
    return new Sender();
  }
}

SendMessage Service:

public class SendMessage {  
    @Autowired
    Sender sender;

    public SendMessage(String message){
        this.sender.send(message);
    }
}

So essentially the error is stemming from the SendMessage class, it's unable to autowire the sender bean but I'm not sure why this error is happening because the Sender bean is being created in the SenderConfig class hence surely Spring should've added it to it Spring container/Bean factory/application context?

This is the stacktrace:

Exception in thread "main" java.lang.NullPointerException
    at com.codenotfound.jms.SendMessage.<init>(SendMessage.java:11)
    at com.codenotfound.SpringJmsApplication.main(SpringJmsApplication.java:16)
Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
tcho1506996
  • 105
  • 6

2 Answers2

1

Here is the culprit in your main class.

SendMessage send = new SendMessage("This is the test message");

You are creating object yourself instead of getting from the context, Spring DI won't be applied to the objects created by ourself.

Solution is, mark the SendMessage as spring managed bean by annotating with @Component and get it from context.

Lovababu Padala
  • 2,415
  • 2
  • 20
  • 28
1

Your problem doesn't stem from SendMessage class, this class seems OK.

Your NPE is caused by the way you obtain an instance of SendMessage class, namely, you're not really obtaining the @Bean, managed by Spring Container; rather, you're creating it manually with a new keyword, as:

SendMessage send = new SendMessage("This is the test message");

This allocates a completely new object in the Heap, which is not going to end up in the Spring Container, hence → is not going to be managed by Spring, hence → its field sender will not be @Autowired.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
  • 1
    Thanks. Managed to inject the application context in the main class (which now implements CommandLineRunner as I can't inject into the `public static void main(String[] args)` method. I am now getting the SendMessage bean via `SendMessage sendMessage = applicationContext.getBean(SendMessage.class);`) – tcho1506996 Aug 01 '20 at 12:54