I am writing a reporting service to receive messages from Azure Service Bus topic subscriptions.
I followed this initial guide - How to use the Spring Boot Starter for Azure Service Bus JMS and simply configured the @JmsListener
in my service files to not specify a JmsConnectionFactory
so that it would fall back to the default, however this returned the error logs shown below, with jmsConnectionFactory
Bean returning a NullPointerException
.
I subsequenly looked at Bauldung - Getting Started with Spring JMS
and Baeldung - Messaging with JMS for guidance on how to configure the jmsConnectionFactory
when the initial implementation wouldn't run but had no luck with any of the suggestions mentioned in the articles above as it was still returning the error logs below.
I then had a dig here on StackOverflow and found this question - Spring Boot - Error creating bean with name 'jmsConnectionFactory', which then pointed to this question - Disabling Spring JMS Auto configuration in Spring Boot Application and this lead me to exclude ServiceBusJMSAutoConfiguration::class
in my @SpringBootApplication
. This actually worked but I find it a little strange that I should need to exclude this class, and feel as though there is something else I may be doing wrong.
I'm basically looking for any insight on whether what I'm doing is normal practice or if there is a better way to go about this set-up, as I'm not particulary a fan of this - @SpringBootApplication(exclude = [ServiceBusJMSAutoConfiguration::class])
. To me it seems like some kind of hack to solving an underlying issue. Any help/opinions on this would be greatly appreciated.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ReportingServiceApplication.kt
@SpringBootApplication(exclude = [ServiceBusJMSAutoConfiguration::class])
class ReportingServiceApplication
fun main(args: Array<String>) {
runApplication<ReportingServiceApplication>(*args)
}
Sample Listener - AwardEditEventService.kt
interface AwardEditEventService {
fun receiveMessage(awardEditEvent: AwardEditEvent)
}
@Service
class AwardEditEventServiceImpl(
val awardEditEventsRepository: AwardEditEventRepository
) : AwardEditEventService {
@JmsListener(
destination = "reporting",
subscription = "AwardEdits"
)
override fun receiveMessage(awardEditEvent: AwardEditEvent) {
awardEditEventsRepository.save(awardEditEvent)
}
}
build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.3.4.RELEASE"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
id("com.diffplug.gradle.spotless") version "4.0.1"
kotlin("jvm") version "1.3.72"
kotlin("plugin.spring") version "1.3.72"
kotlin("plugin.jpa") version "1.3.72"
}
group = "com.test.service"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
// Kotlin
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// Spring Boot
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
// Flyway
implementation("org.flywaydb:flyway-core")
// App Insights
implementation("com.microsoft.azure:applicationinsights-spring-boot-starter:2.6.1")
implementation("com.microsoft.azure:applicationinsights-logging-logback:2.6.1")
// Azure Service Bus
implementation("com.microsoft.azure:azure-servicebus-spring-boot-starter:2.2.5")
implementation("com.microsoft.azure:azure-servicebus-jms-spring-boot-starter:2.2.5")
// Snowflake
implementation("net.snowflake:snowflake-jdbc:3.12.12")
// Postgres (For Local Development)
runtimeOnly("org.postgresql:postgresql")
// Test
testImplementation("com.h2database:h2:1.4.200")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("com.nhaarman:mockito-kotlin:1.6.0")
testImplementation("org.hamcrest:hamcrest-library:2.2")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
Here are the logs for the initial error -
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsConnectionFactory' defined in class path resource [com/microsoft/azure/spring/autoconfigure/jms/ServiceBusJMSAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'jmsConnectionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:635) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at com.test.service.reporting.ReportingServiceApplicationKt.main(ReportingServiceApplication.kt:13) ~[main/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'jmsConnectionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
... 20 common frames omitted
Caused by: java.lang.NullPointerException: null
at com.microsoft.azure.spring.autoconfigure.jms.ConnectionStringResolver.getServiceBusKey(ConnectionStringResolver.java:30) ~[azure-spring-boot-2.2.5.jar:na]
at com.microsoft.azure.spring.autoconfigure.jms.ServiceBusJMSAutoConfiguration.jmsConnectionFactory(ServiceBusJMSAutoConfiguration.java:40) ~[azure-spring-boot-2.2.5.jar:na]
at com.microsoft.azure.spring.autoconfigure.jms.ServiceBusJMSAutoConfiguration$$EnhancerBySpringCGLIB$$9ce4d56.CGLIB$jmsConnectionFactory$3(<generated>) ~[azure-spring-boot-2.2.5.jar:na]
at com.microsoft.azure.spring.autoconfigure.jms.ServiceBusJMSAutoConfiguration$$EnhancerBySpringCGLIB$$9ce4d56$$FastClassBySpringCGLIB$$99b2393f.invoke(<generated>) ~[azure-spring-boot-2.2.5.jar:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at com.microsoft.azure.spring.autoconfigure.jms.ServiceBusJMSAutoConfiguration$$EnhancerBySpringCGLIB$$9ce4d56.jmsConnectionFactory(<generated>) ~[azure-spring-boot-2.2.5.jar:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
... 21 common frames omitted