Slow startup on spring integration test. Cause? Can't disable RabbitMQ - spring

I'm struggling in a performance problem on startup with my integration tests.
I'm trying to mock the messaging of the system. To do that, I basically use #MockBean on my gateway and use #EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}). Example:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = MyApplication.class)
#WebAppConfiguration
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
#ActiveProfiles("test")
#EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class})
public class MyTestIT {
These two configuration did the job very well, my tests run without problem and without any dependency with some external RabbitMQ.
But the startup time of the spring boot is very, very slow. It's about two minutes only in this part configuring SimpleMessageListenerContainer, AmqpInboundChannelAdapter, EventDrivenConsumer, RabbitExchangeQueueProvisioner, etc.
The log has some tips about what is the problem (I cut a lot of the messages, this is a sample):
2018-02-09 14:26:37.784 INFO [ms-project-name-service,,,] 13804 --- [ main] o.s.integration.channel.DirectChannel : Channel 'ms-project-name-service:test:-1.channel2-output' has 1 subscriber(s).
2018-02-09 14:26:54.110 INFO [ms-project-name-service,,,] 13804 --- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: channel1-input.anonymous.417FtxKTTce7-_IR0tGuNA, bound to: channel1-input
2018-02-09 14:27:00.147 INFO [ms-project-name-service,,,] 13804 --- [ main] o.s.c.stream.binder.BinderErrorChannel : Channel 'ms-project-name-service:test:-1.channel1-input.anonymous.417FtxKTTce7-_IR0tGuNA.errors' has 2 subscriber(s).
2018-02-09 14:27:09.186 INFO [ms-project-name-service,,,] 13804 --- [ce7-_IR0tGuNA-1] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer#4f0ea6f8: tags=[{}], channel=null, acknowledgeMode=AUTO local queue size=0
The most strange is this one:
2018-02-09 14:58:42.783 WARN [ms-project-name-service,,,] 208 --- [geGeQP_9Li3Jg-1] o.s.a.r.l.SimpleMessageListenerContainer : Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
This last one seems that he is still trying to connect on a local RabbitMQ.
There are a lot of these messages on the log. I can't understand why this is still happening even with RabbitMQAutoConfiguration disabled. It's a mystery too how the spring is subscribing in a channel if there is no RabbitMQ to connect.

We had similar problem here and it was solved by changing the runner:
#RunWith(SpringRunner.class)
to
#RunWith(SpringJUnit4ClassRunner.class)
They seems like the same on the documentation, but really kickoff our test performance.
Let me know if it work, I'm still looking into the documentation for more details.

After #Marco response, the problem was back after I removed the follow dependency of my pom.xml (for instance, it is my first dependency on <dependencies/>:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support</artifactId>
<scope>test</scope>
</dependency>
After return the dependency, the problem was soved. I changed to SpringRunner.class and the tests continued to be fast. I removed the dependency and the tests turned slow again...
I think it's a bug related with the Spring looking for the classpath to do the auto configuration.
By the way, some of the messages on log continues to happen, but they not take so long.
Other thing that help is use this configuration for your tests:
#Configuration
public class RabbitMqConfiguration {
#Bean
ConnectionFactory connectionFactory() {
return new CachingConnectionFactory();
}
}

Related

The camel context initiates shutdown immediately after application start, with no apparent error

My spring-boot app starts a Camel route that consumes from a Kafka-enabled Azure event hub. Immediately after the message that the Application has started, this message is logged: "INFO o.a.camel.spring.SpringCamelContext - Apache Camel 2.24.0 (CamelContext: camel-1) is shutting down".
Then any in-flight exchanges (if they exist) are successfully processed by the Camel route, and eventually the route is shutdown (gracefully), which also terminates the app.
No error messages are shown, nothing seems to be wrong, except that the shutdown is initiated automatically right after the application starts....
Any idea why this happens ?
I have played around with the timeouts for Kafka, but there's no change in behavior.
I have set the logging level to TRACE, but still I don't see why shutdown is initiated.
Among others, I use these libraries: spring-boot-starter, spring-boot-starter-web, azure-servicebus-spring-boot-starter, camel-kafka, camel-spring-boot-starter, camel-undertow-starter
This is how the route starts:
from("kafka:dummytopic?brokers=dummy.servicebus.windows.net:9093&topic={{event.hubs.hub.magento}}&groupId={{event.hubs.consumer-group}}"
+ "&consumersCount=1"
+ "&autoOffsetReset=latest"
+ "&saslMechanism=PLAIN"
+ "&securityProtocol=SASL_SSL"
+ "&sslProtocol=TLSv1.2"
+ "&sslEnabledProtocols=TLSv1.2"
+ "&sslEndpointAlgorithm=HTTPS"
+ "&saslJaasConfig=" + saslJaasConfig
+ "&autoCommitEnable=true")
.....
Normally the route should keep running and polling the kafka Event Hub for events (and process them when they are available).
Instead, it initiates shutdown immediately (still successfully processing any in-flight exchanges) - it simply shuts down gracefully. No error messages.
Any help is appreciated!
PS: this is an extract from the trace log:
15:01:40.867 [main] INFO c.i.s.n.NotificationMicroserviceApplication - Started NotificationMicroserviceApplication in 10.516 seconds (JVM running for 14.643)
15:01:40.868 [main] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'camelContext'
15:01:40.868 [main] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'springApplicationAdminRegistrar'
15:01:40.868 [main] DEBUG o.a.camel.spring.SpringCamelContext - onApplicationEvent: org.springframework.boot.context.event.ApplicationStartedEvent[source=org.springframework.boot.SpringApplication#22aefae0]
15:01:40.870 [main] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'camelContext'
15:01:40.870 [main] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'springApplicationAdminRegistrar'
15:01:40.870 [main] DEBUG o.a.camel.spring.SpringCamelContext - onApplicationEvent: org.springframework.boot.context.event.ApplicationReadyEvent[source=org.springframework.boot.SpringApplication#22aefae0]
15:01:40.872 [Thread-37] DEBUG o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#2cd2a21f, started on Thu Jun 06 15:01:31 EEST 2019
15:01:40.873 [Thread-37] TRACE o.s.c.e.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in PropertySource 'configurationProperties'
15:01:40.873 [Thread-37] TRACE o.s.c.e.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in PropertySource 'systemProperties'
15:01:40.873 [Thread-37] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'spring.liveBeansView.mbeanDomain' in PropertySource 'systemProperties' with value of type String
15:01:40.874 [Thread-37] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'camelContext'
15:01:40.874 [Thread-37] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'springApplicationAdminRegistrar'
15:01:40.875 [Thread-37] DEBUG o.a.camel.spring.SpringCamelContext - onApplicationEvent: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext#2cd2a21f, started on Thu Jun 06 15:01:31 EEST 2019]
15:01:40.877 [Thread-37] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'camelContext'
15:01:40.877 [Thread-37] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
15:01:40.879 [Thread-37] DEBUG o.s.c.s.DefaultLifecycleProcessor - Stopping beans in phase 2147483647
15:01:40.879 [Thread-37] TRACE o.s.c.s.DefaultLifecycleProcessor - Stopping bean 'camelContext' of type [org.apache.camel.spring.SpringCamelContext]
15:01:40.879 [Thread-37] INFO o.a.camel.spring.SpringCamelContext - Apache Camel 2.24.0 (CamelContext: camel-1) is shutting down
15:01:40.879 [Thread-37] TRACE org.apache.camel.util.ServiceHelper - Stopping service org.apache.camel.impl.DefaultRouteController#108b121f
15:01:40.879 [Thread-37] TRACE org.apache.camel.util.ServiceHelper - Shutting down service org.apache.camel.impl.DefaultRouteController#108b121f
15:01:40.879 [Thread-37] TRACE o.a.camel.support.ServiceSupport - Service already stopped
15:01:40.880 [Thread-37] INFO o.a.c.impl.DefaultShutdownStrategy - Starting to graceful shutdown 1 routes (timeout 300 seconds)
15:01:40.880 [Thread-37] TRACE o.a.c.m.DefaultManagementLifecycleStrategy - Checking whether to register org.apache.camel.util.concurrent.RejectableThreadPoolExecutor#11ee4d34[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0][ShutdownTask] from route: null
15:01:40.880 [Thread-37] DEBUG o.a.c.i.DefaultExecutorServiceManager - Created new ThreadPool for source: org.apache.camel.impl.DefaultShutdownStrategy#58b97c15 with name: ShutdownTask. -> org.apache.camel.util.concurrent.RejectableThreadPoolExecutor#11ee4d34[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0][ShutdownTask]
15:01:41.073 [Thread-37] TRACE o.a.c.u.c.CamelThreadFactory - Created thread[Camel (camel-1) thread #2 - ShutdownTask] -> Thread[Camel (camel-1) thread #2 - ShutdownTask,5,main]
15:01:41.075 [Camel (camel-1) thread #2 - ShutdownTask] DEBUG o.a.c.impl.DefaultShutdownStrategy - There are 1 routes to shutdown
15:01:41.075 [Camel (camel-1) thread #2 - ShutdownTask] TRACE o.a.c.impl.DefaultShutdownStrategy - Shutting down route: routeEventHub with options [Default,CompleteCurrentTaskOnly]
You can see that at 15:01:40.872 it starts closing things down...
I had the same problem, for me case the solution it was add the next depency into pom file.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
There is no thread that keeps the application alive. That's why it immediately shutsdown.
You may want to add spring-boot-starter-web to have a web container that is running or you could have a loop in our main class that prevents the shutdown.
I would go for the web container. So you could also add the actuator framework with some diagnostic information.
This is related to spring version upgrade.
The problem described is related to conflicts between different Maven dependencies. I've had the same problem while trying to use the latest version of Spring Boot with Apache Camel.
After analyzing the dependency tree, it turned out that the version of spring-webmvc was 5.2.9, while all other spring dependencies were of version 5.2.8.
I have solved the problem by using a newer version of camel-spring-boot-dependencies (3.6.0)
Eventually, this solution worked:
#Slf4j
#SpringBootApplication
public class NotificationMicroserviceApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(NotificationMicroserviceApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
log.info("You can press Ctrl+C anytime to shutdown application");
Thread.currentThread().join();
}
}

rabbitConnectionFactory autodetected for JMX exposure

I have a Spring Boot application that supports Kafka. Recently I am trying to make it also support RabbitMQ. I set up the code using the #Profile annotation so that all the new code for RabbitMQ should be active only if I select spring.profiles.active to be rabbit-mq. Likewise, the Kafka-specific code are marked out by profile value of kafka
I was surprise to see that even with the above setup, when I set the profile to be kafka, some RabbitMQ is still included and activated, through a mechanism JMX exposure. Specifically, a rabbitConnectionFactory bean was constructed, and then it tried to do health check with a RabbitMQ broker at localhost:5672, and failed.
In the log file, I saw these messages:
... o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
... o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'rabbitConnectionFactory' has been autodetected for JMX exposure
... o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'rabbitConnectionFactory': registering with JMX server as MBean [org.springframework.amqp.rabbit.connection:name=rabbitConnectionFactory,type=CachingConnectionFactory]
... o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483547
... o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
... o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
... c.s.datacomparatorproducer.Application : Started Application in 5.175 seconds (JVM running for 5.663)
... o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
... o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
... o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 15 ms
... o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672]
... o.s.b.a.amqp.RabbitHealthIndicator : Rabbit health check failed
org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:476) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:614) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:240) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1797) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1771) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
I have two questions:
How can I avoid RabbitMQ code from being included? Why my set up using #Profile did not work as expected?
How do I configure the rabbitConnectionFactory? Currently it is trying to talk to localhost:5672. I know how to, in general, set up Spring template to use application-xxx.properties for spring.rabbitmq.{host,port}, but in this case, since the code is auto-included, I don't know how to configure rabbitConnectionFactory
Usual configuration
spring.rabbitmq.host=someRabbitBroker
spring.rabbitmq.port=5672
Update
Attempt 1: Excluding RabbitAutoConfiguration
Thank you Gary Russell for the suggestion. I tried his method and changed my #SpringBootApplication as follows. The idea here is to exclude RabbitAutoConfiguration when spring.rabbitmq.host is NOT defined (when the profile of rabbit-mq is not active):
#SpringBootApplication
public class Application {
#ConditionalOnProperty(value="spring.rabbitmq.host")
#Bean
RabbitAutoConfiguration rabbitAutoConfiguration(){
return new RabbitAutoConfiguration();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I am not sure if this code is the correct way to do it, but it did not work. When my app started, I still saw these in the message:
... o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
... o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'rabbitConnectionFactory' has been autodetected for JMX exposure
... o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'rabbitConnectionFactory': registering with JMX server as MBean [org.springframework.amqp.rabbit.connection:name=rabbitConnectionFactory,type=CachingConnectionFactory]
... o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483547
I am okay with having the bean constructed, as long as I can stop it from doing health check (or at least configure it to use my designated host and port). Is there a way to do this?
You either need to exclude the spring-rabbit jar from the classpath or disable rabbitmq auto-configuration by excluding RabbitAutoConfiguration from the #SpringBootApplication.
Update: disabling health check
See the boot properties documentation. Specifically set management.health.rabbit.enabled to false

Problem with Google Cloud Pub/Sub API and Spring boot application

I write spring boot application for subscribing Google cloud Pub/Sub topic for this I use Google's tutorial, but when I run application I have get this error
2019-02-02 18:03:10.248 INFO 15080 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2019-02-02 18:03:10.271 INFO 15080 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-02-02 18:03:10.610 ERROR 15080 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of method messageChannelAdapter in tech.garoon.cloud.CloudApplication required a bean of type 'org.springframework.cloud.gcp.pubsub.core.PubSubTemplate' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.cloud.gcp.pubsub.core.PubSubTemplate' in your configuration.
Process finished with exit code 1
How Can I solve this problem?
GcpPubSubAutoConfiguration provides autoconfiguration feature of creating necessary beans including PubSubTemplate. In your case, somethng is missed, Kindly ensure that dependencies are in place or recreate following bean to make it work.
#Bean
public PubSubTemplate pubSubTemplate(PubSubPublisherTemplate pubSubPublisherTemplate,
PubSubSubscriberTemplate pubSubSubscriberTemplate) {
return new PubSubTemplate(pubSubPublisherTemplate, pubSubSubscriberTemplate);
}
Additionally, make sure GcpContextAutoConfiguration is created based on below properties in application.properties.
spring.cloud.gcp.credentials.location=${gcp_credentials}
starter dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>
Solution
I added this dependency
implementation 'org.springframework.cloud:spring-cloud-gcp-autoconfigure:1.1.0.RELEASE'
My dependencies
dependencies {
implementation 'org.springframework.cloud:spring-cloud-gcp-pubsub:1.1.0.RELEASE'
implementation 'org.springframework.cloud:spring-cloud-gcp-autoconfigure:1.1.0.RELEASE'
implementation "org.springframework.boot:spring-boot-starter-web:2.1.2.RELEASE"
implementation 'org.springframework.integration:spring-integration-core:5.1.2.RELEASE'
}
if using external configuration class that is registering your channels, message handlers etc, make sure to annotate the configuration class with #Import({GcpPubSubAutoConfiguration.class})
#Configuration
#Import({GcpPubSubAutoConfiguration.class})
public class PubSubConfig{
}
I ran into this issue with these versions of spring-boot and spring-cloud-gcp-starter-pub:
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
and in my application.properties I had
spring.cloud.gcp.pubsub.enabled=false for local development.
I removed spring.cloud.gcp.pubsub.enabled=false and it worked. Although now it creates a connection to the pubsub gcp topic, so for local development, you will need to comment out publishing, to avoid sending messages.

spring-boot client unable to start with consul

I have setup and run consul using docker on my system using following command:
sudo docker run -p 8500:8500 consul:0.9.2
Consul is running fine as I can check from the consul UI (Image attached below):
Now, I am trying to run my spring-boot service to use this consul instance for service discovery and registration. But, whenever i start it gives me following exception:
2017-09-02 18:58:17.091 ERROR 5578 --- [ restartedMain] o.s.c.c.c.ConsulPropertySourceLocator : Fail fast is set and there was an error reading configuration from consul.
2017-09-02 18:58:18.183 ERROR 5578 --- [ restartedMain] o.s.c.c.c.ConsulPropertySourceLocator : Fail fast is set and there was an error reading configuration from consul.
2017-09-02 18:58:19.375 ERROR 5578 --- [ restartedMain] o.s.c.c.c.ConsulPropertySourceLocator : Fail fast is set and there was an error reading configuration from consul.
2017-09-02 18:58:20.691 ERROR 5578 --- [ restartedMain] o.s.c.c.c.ConsulPropertySourceLocator : Fail fast is set and there was an error reading configuration from consul.
2017-09-02 18:58:22.114 ERROR 5578 --- [ restartedMain] o.s.c.c.c.ConsulPropertySourceLocator : Fail fast is set and there was an error reading configuration from consul.
2017-09-02 18:58:23.671 ERROR 5578 --- [ restartedMain] o.s.c.c.c.ConsulPropertySourceLocator : Fail fast is set and there was an error reading configuration from consul.
2017-09-02 18:58:23.691 ERROR 5578 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed
com.ecwid.consul.v1.OperationException: OperationException(statusCode=500, statusMessage='Internal Server Error', statusContent='No cluster leader')
at com.ecwid.consul.v1.kv.KeyValueConsulClient.getKVValues(KeyValueConsulClient.java:159)
at com.ecwid.consul.v1.ConsulClient.getKVValues(ConsulClient.java:487)
at org.springframework.cloud.consul.config.ConsulPropertySource.init(ConsulPropertySource.java:66)
at org.springframework.cloud.consul.config.ConsulPropertySourceLocator.create(ConsulPropertySourceLocator.java:157)
at org.springframework.cloud.consul.config.ConsulPropertySourceLocator.locate(ConsulPropertySourceLocator.java:131)
at org.springframework.cloud.consul.config.ConsulPropertySourceLocator$$FastClassBySpringCGLIB$$b35ebf8.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:91)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:286)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:163)
at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:118)
at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.springframework.cloud.consul.config.ConsulPropertySourceLocator$$EnhancerBySpringCGLIB$$66375879.locate(<generated>)
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:93)
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:567)
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:338)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:301)
at com.pyg.auth.AuthServiceApp.main(AuthServiceApp.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
SpringBoot Main Class is annotated fine (I guess), because my spring-boot service was working fine with another consul instance earlier.
I was able to solve my issue by moving consul server and port configuration from application.yml to bootstrap.yml.
I don't know much about how it was solved and why it was unable to read from application.yml. If anyone has some details about it, pl. let me know.
Use sudo docker run -p 8500:8500 consul:0.9.2 -bootstrap to resolve the problem. I have
added -bootstrap one argument to bootstrap the server/servers and get elected as a leader. Manual bootstrapping with -bootstrap is not recommended in newer versions of Consul (0.5 and newer) as it is more error-prone.
Explanation:-
As said in docs Before a Consul cluster can begin to service requests, a server node must be elected leader. And this is reason of your exception on start of spring-boot service the leader has not been elected yet!!
Why the leader has not been elected? The list of servers involved in the cluster should be bootstrapped. And the servers can be bootstrapped using the
-bootstrap-expect configuration option. Recommended
Note:- Just for testing/learning purpose you can go ahead and create a single server because A single server deployment is highly discouraged as data loss is inevitable in a failure scenario.
Check your pom.xml.
Don't use spring-cloud-starter-consul-all. Use spring-cloud-starter-consul-discovery instead.
That worked for me.
Please check pom.xml to avoid using spring-cloud-starter-consul-all
If you use spring-cloud-starter-consul-all, please write the configuration to bootstrap.yml, the bootstrap.yml configuration file is the first to load.

Application context being loaded twice - Spring Boot

I have a fairly simple setup. A maven project with 3 modules : core/webapp/model. I'm using Spring boot to gear up my application. In webapp, i have a simple class WebappConfig as follows:
#Configuration
#EnableAutoConfiguration
#ComponentScan(excludeFilters = #ComponentScan.Filter(Configuration.class))
public class WebappConfig {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(WebappConfig.class);
app.setAdditionalProfiles("dev");
app.run(args);
}
}
and few classes in core/model module. My container-application point is :
public class AbcdXml extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebappConfig.class);
}
}
And no web.xml! My model's pom has following spring boot related dependency :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Core's pom.xml :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
Now running WebappConfig via Run as -> Java application works perfectly but i need to deploy the project as a war on tomcat7. Webapp's packaging is war. There is no tomcat provided jar's in lib except tomcat-jdbc and tomcat-tuli jar(Shouldn't be an issue?).
When i deploy my abcd.war, applicationcontext is getting loaded twice and result in following error stracktrace :
2014-06-27 11:06:08.445 INFO 23467 --- [ost-startStop-1] o.a.c.c.C.[.[localhost].[/abcd] : Initializing Spring embedded WebApplicationContext
2014-06-27 11:06:08.446 INFO 23467 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 19046 ms
2014-06-27 11:06:21.308 INFO 23467 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-06-27 11:06:21.313 INFO 23467 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
2014-06-27 11:06:21.314 INFO 23467 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2014-06-27 11:06:26.073 INFO 23467 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2014-06-27 11:06:26.127 INFO 23467 --- [ost-startStop-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2014-06-27 11:06:26.511 INFO 23467 --- [ost-startStop-1] org.hibernate.Version : HHH000412: Hibernate Core {4.3.1.Final}
2014-06-27 11:06:26.521 INFO 23467 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2014-06-27 11:06:26.527 INFO 23467 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
//some info messages from spring boot
2014-06-27 11:07:31.664 INFO 23467 --- [ost-startStop-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-06-27 11:07:33.095 INFO 23467 --- [ost-startStop-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-06-27 11:07:33.096 INFO 23467 --- [ost-startStop-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-06-27 11:07:36.080 INFO 23467 --- [ost-startStop-1] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2014-06-27 11:08:49.583 INFO 23467 --- [ost-startStop-1] o.s.boot.SpringApplication : Started application in 183.152 seconds (JVM running for 210.258)
2014-06-27 11:12:29.229 ERROR 23467 --- [ost-startStop-1] o.a.c.c.C.[.[localhost].[/abcd] : Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:277)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:976)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1653)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
There is no web.xml as i mentioned earlier.
Few interesting things that i can't figure out why :
After exploding the war, tomcat somehow create a ROOT folder with default web.xml[Must be Spring boot misconfiguration. How can i correct it? Pointers please?]
Even if i return same 'application' SpringApplicationBuilder in AbcdXml.java, i am facing the same issue of applicationcontext being loaded twice.
Thanks for your help!
EDIT 1:
Content of web.xml that is generated in ROOT folder :
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd" version="2.5">
</web-app>
If your app includes jersey-spring3 and you don't take steps to disable, it will try to create an ApplicationContext for you (helpful, not). There is a way to switch it off (in a WebApplicationInitializer):
servletContext.setInitParameter("contextConfigLocation", "<NONE>");
Or just use this: https://github.com/dsyer/spring-boot-jersey (include as a dependency).
In my case - I was having the same problem - seeing the Spring splash screen twice - It was because I had 2 classes that extended SpringBootServletInitializer. One was called SpringBootWebApplication and the other ServletInitializer. I just removed the ServletInitializer and it worked OK. Don't know why there were 2 classes - maybe because I got inspired from 2 different examples to assemble what I needed.
In my case the culprit was using Spring Boot 1.3.0.M4, along with Jersey 2.21. When I downgraded Spring Boot to 1.2.6.RELEASE the issue is gone.
The only thing I had to do was to explicitly override the following properties, as I needed spring 4.2.0 for Hibernate 5 support, and jackson 2.6.2 for JSR310 (java8 java.time) support:
<spring.version>4.2.0.RELEASE</spring.version>
<jackson.version>2.6.2</jackson.version>
EDIT: As of spring-boot 1.3.0.RELEASE, this bug still exists. See github
My main problem was my spring context was being loaded twice. As I printed every class's class loader I found that my Application was running twice. (i.e. when I debug in intellij after pressing F9 I was again landing up on same line i.e.
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigAssignServer.class, args);
My problem was in pom.xml. I removed below dependency from my pom and it worked.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
Please check for your dependencies. Hope it will help someone. Enjoy coding :)
I had the same issue
I have src>main>webapp>WEB-INF>web.xml has an entity to saying
<listener>
<listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
</listener>
This is loading my context second time.
Comment it out and it will load only once.
I'm using Spring Boot 2.5.5 and experiencing the same issue but without error (WebApplicationContext) is being loaded twice along with scheduler calls are triggered as well too.
After debugging my application & Server(Tomcat v9.0.53) settings, I, myself able to solve the issue by deleting the "ServletInitializer.java" class which comes part of Spring initialiser project.
Now, all the issues resolved like schedulers are called once on predefined time along with the context loading.
Hope this resolves the issue.
Seems that "extends SpringBootServletInitializer" not work well with #SpringBootApplication in tomcat but when run with maven no duplicated beans is initialized so removing "extends SpringBootServletInitializer" from application main class solve the problem
In the Spring framework, usually for loading something like a global or root context, you club all the bean/resources shared by multiple servlet contexts.
Or loading a specific servlet context. Mvc-dispatcher config file is used to load config file, so you don't need to explicitly define it.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
In your case, seems when you are running as a Java application, auto-detection of Mvc-dispatcher doesn't happen and you are able to execute the code successfully. Whereas when deployed it gets initiated both from root and mvc-dispatcher.
Use empty context: <context-param/>
I don’t see the contents of web.xml here, So I am throwing a quick suggestion from both perspectives.
Please try to delete dependency from the global/root context.
Or in case #EnableAutoConfiuguration is used, get rid of it.
#EnableAutoConfiuguration from the API says "Enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need."
#ComponentScan would also instantiate the beans. IT will scan the packages, find and register the beans.
As you are using both these annotations, I guess that is why its loading twice.

Resources