I have an example project here. In this multi module project. I have module promotion-service on which the PromotionConfiguration relies on other configurations to be completed first.
#Configuration
#AutoConfigureAfter({RulesConfiguration.class, PointsConfiguration.class})
public class PromotionConfiguration
{
#Bean
public PromotionService promotionService(ObjectProvider<List<Rule>> rules)
{
System.out.println("Adding PromotionService to context");
List<Rule> ruleList = rules.getIfAvailable();
if (!ruleList.isEmpty())
{
ruleList.sort(Comparator.comparingInt(Rule::getOrder));
}
return new PromotionServiceImpl(ruleList);
}
}
But when the spring boot application that has a dependency of module promotion-service the rules are added to the context after the promotion-service is
2018-02-18 11:20:26.743 INFO 11582 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
Adding PromotionService to context
Adding PointRule to context.
Adding PromotionRule to context.
2018-02-18 11:20:27.087 INFO 11582 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for #ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#196a42c3: startup date [Sun Feb 18 11:20:25 EST 2018]; root of context hierarchy
There is a difference between parsing the configuration and its structure and effectively creating beans at runtime. What is the concrete problem here?
If I run your project, the promotionService is created with 2 rules as you'd expect. If I add #ConditionalOnMissingBean(Rule.class) on promotionService it is not created (which proves the context knows that at least one Rule bean is going to be created).
You shouldn't worry too much about the runtime part, the context is free to invoke the necessary factory methods (i.e. #Bean annotated methods) according to its optimized plan (it namely does smart stuff to resolve cycles).
The reason why you get this log output is that you're not asking the context to resolve the Rule beans. ObjectProvider is a proxy that won't do anything until you ask for something (getAvailable in this case).
I've changed the injection point to use List<Rule> and I got the following:
Adding PointRule to context.
Adding PromotionRule to context.
Adding PromotionService to context
So all is good. But please, rename your auto-configuration so that they ends with AutoConfiguration rather than Configuration.
Related
I have a Spring batch application which uses some sql scripts to initialise the database.
When I extend the application by Spring Batch functionality I need to instantiate the JobRegistryBeanPostProcessor bean in order to use JobRegistry.
I use a similar method as in https://github.com/jbbarquero/spring-batch-sample/blob/master/src/main/java/com/malsolo/springframework/batch/sample/BatchConfiguration.java
However with such addition I have got a problem - sql scripts are not executed anymore.
In the log output I mentioned such new INFO messages with different bean names (XXX) :
] trationDelegate$BeanPostProcessorChecker : Bean XXX is not eligible
for getting processed by all BeanPostProcessors (for example: not
eligible for auto-proxying)
Is there an approach to resolve the problem aforementioned ?
There is a following solution to the problem:
instead of instantiating the JobRegistryBeanPostProcessor bean, directly register the job in the jobRegistry as proposed in https://stackoverflow.com/a/53381283/6931863
Such solution enables initialisation of Database from data.sql as well as stopping jobs using jobOperator.stop.
I've been using this guide to set up spring session data with mongodb
https://docs.spring.io/spring-session-data-mongodb/docs/2.1.1.RELEASE/reference/htmlsingle/#introduction
However I am having problems with configuration. I'm using Mongodb with Spring boot and I'm trying to config my session time and session name for Spring boot web application, but it keeps defaulting to 30 minutes and the collection name in mongodb is still 'sessions'
These are what I have tried:
Added these to application.properties:
server.session.timeout=1
spring.session.mongodb.collection-name=TestSESSIONS
and this
server.servlet.session.timeout=60s
spring.session.mongodb.collection-name=TestSESSIONS
none of those config work
I've looked over this URL for spring common application properties for mongodb but none of it help to config the session time and collection name for mongodb.
After doing hours of research it seems like spring boot uses some kind of autoconfig with this "org.springframework.boot.autoconfigure"
so then I added this in my application.properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
to disable the autoconfigure.
but now it just give me this error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method mongoSessionRepository in org.springframework.session.data.mongo.config.annotation.web.http.MongoHttpSessionConfiguration required a bean of type 'org.springframework.data.mongodb.core.MongoOperations' that could not be found.
The following candidates were found but could not be injected:
- Bean method 'mongoTemplate' in 'MongoDataAutoConfiguration' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on MongoDataAutoConfiguration.AnyMongoClientAvailable.FallbackClientAvailable #ConditionalOnBean (types: com.mongodb.client.MongoClient; SearchStrategy: all) did not find any beans of type com.mongodb.client.MongoClient; NestedCondition on MongoDataAutoConfiguration.AnyMongoClientAvailable.PreferredClientAvailable #ConditionalOnBean (types: com.mongodb.MongoClient; SearchStrategy: all) did not find any beans of type com.mongodb.MongoClient
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.data.mongodb.core.MongoOperations' in your configuration.
this is the #bean from the spring.io guide 'mongoSessionConverter' from above link
this is the java file MongoHttpSessionConfiguration from spring that that's autoconfig by spring; I have tried extending "MongoHttpSessionConfiguration" and overriding the setter methods my self. Such as the "setMaxInactiveIntervalInSeconds" for sessionTime and
"setCollectionName" for mongododb database collection name.
but I've have this error:
Description:
The bean 'mongoSessionRepository', defined in class path resource [com/khatpass/app/config/SessionListenerConfig.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfiguration.class] and overriding is disabled.
I am stuck on trying to configure spring boot session with Mongodb. The session always defaulting to 30 minutes and the collection name is always 'sessions' in mongodb collections. Not sure how to change that serverSelectionTimeout='30000 ms' and mongodb collections name "sessions" I don't know what to do, need help.
2019-02-24 13:39:54.501 INFO 36113 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[localhost:27017], mode=MULTIPLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
After doing so much research and then finally, going through the source code, I found the solution:
#EnableMongoHttpSession(maxInactiveIntervalInSeconds = 24 * 60 * 60)
public class SessionConfiguration {}
To override the default collection name, there is another annotation attribute collectionName.
This is working for Spring Boot 2.1.1
After looking over the class MongoOperationsSessionRepository from org.springframework.session.data.mongo it seems like it can't be config through application.properties because the class is using static final values
public static final int DEFAULT_INACTIVE_INTERVAL = 1800;
and
public static final String DEFAULT_COLLECTION_NAME = "sessions";
only way to change the value is intercept the object before it gets saved. No getters or setters for those fields, it can't be change in an easy way, what a joke!
I have used STS and now I am using IntelliJ Ultimate Edition but I am still getting the same output. My controller is not getting mapped thus showing 404 error. I am completely new to Spring Framework.
DemoApplication.java
package com.webservice.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
HelloController.java
package com.webservice.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HelloController {
#RequestMapping("/hello")
public String sayHello(){
return "Hey";
}
}
Console Output
com.webservice.demo.DemoApplication : Starting DemoApplication on XFT000159365001 with PID 11708 (started by Mayank Khursija in C:\Users\Mayank Khursija\IdeaProjects\demo)
2017-07-19 12:59:46.150 INFO 11708 --- [ main] com.webservice.demo.DemoApplication : No active profile set, falling back to default profiles: default
2017-07-19 12:59:46.218 INFO 11708 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#238e3f: startup date [Wed Jul 19 12:59:46 IST 2017]; root of context hierarchy
2017-07-19 12:59:47.821 INFO 11708 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8211 (http)
2017-07-19 12:59:47.832 INFO 11708 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2017-07-19 12:59:47.832 INFO 11708 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.15
2017-07-19 12:59:47.944 INFO 11708 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-07-19 12:59:47.944 INFO 11708 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1728 ms
2017-07-19 12:59:47.987 INFO 11708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-07-19 12:59:48.510 INFO 11708 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-07-19 12:59:48.519 INFO 11708 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-07-19 12:59:48.634 INFO 11708 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8211 (http)
2017-07-19 12:59:48.638 INFO 11708 --- [ main] com.webservice.demo.DemoApplication : Started DemoApplication in 2.869 seconds (JVM running for 3.44)
I too had the similar issue and was able to finally resolve it by correcting the source package structure following this
Your Controller classes are not scanned by the Component scanning. Your Controller classes must be nested below in package hierarchy to the main SpringApplication class having the main() method, then only it will be scanned and you should also see the RequestMappings listed in the console output while Spring Boot is getting started.
Tested on Spring Boot 1.5.8.RELEASE
But in case you prefer to use your own packaging structure, you can always use the #ComponentScan annotation to define your basePackages to scan.
Because of DemoApplication.class and HelloController.class in the same package
Locate your main application class in a root package above other classes
Take look at Spring Boot documentation Locating the Main Application Class
Using a root package also allows component scan to apply only on your
project.
For example, in your case it looks like below:
com.webservice.demo.DemoApplication
com.webservice.demo.controller.HelloController
In my case, it was missing the dependency from pom.xml, otherwise everything compiled just fine. The 404 and missing mappings info from Spring logs were the only hints.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
I also had trouble with a similar issue and resolved it using the correct package structure as per below. After correction, it is working properly.
e.g.
Spring Application Main Class is in package com.example
Controller Classes are in package com.example.controller
Adding #ComponentScan(com.webservice) in main class above #SpringBootApplication will resolve your problem. Refer below code
package com.webservice.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#ComponentScan(com.webservice)
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
In my case, I was using #Controller instead of #RestController with #RequestMapping
In my opinion, this visibility problem comes when we leave the component scan to Spring which has a particular way of looking for the classes using standard convention.
In this scenario as the Starter class(DemoApplication)is in com.webservice.demo package, putting Controller one level below will help Spring to find the classes using the default component scan mechanism. Putting HelloController under com.webservice.demo.controller should solve the issue.
It depends on a couple of properties:
server.contextPath property in application properties. If it's set to any value then you need to append that in your request url. If there is no such property then add this line in application.properties server.contextPath=/
method property in #RequestMapping, there does not seem to be any value and hence, as per documentation, it should map to all the methods. However, if you want it to listen to any particular method then you can set it to let's say method = HttpMethod.GET
I found the answer to this. This was occurring because of security configuration which is updated in newer versions of Spring Framework. So i just changed my version from 1.5.4 to 1.3.2
In my case I used wrong port for test request - Tomcat was started with several ones exposed (including one for monitoring /actuator).
In my case I changed the package of configuration file. Moved it back to the original com.example.demo package and things started working.
Another case might be that you accidentally put a Java class in a Kotlin sources directory as I did.
Wrong:
src/main
┕ kotlin ← this is wrong for Java
┕ com
┕ example
┕ web
┕ Controller.class
Correct:
src/main
┕ java ← changed 'kotlin' to 'java'
┕ com
┕ example
┕ web
┕ Controller.class
Because when in Kotlin sources directory, Java class won't get picked up.
All other packages should be an extension of parent package then only spring boot app will scan them by default.
Other option will be to use #ComponentScan(com.webservice)
package structure
👋 I set up 🍃Spring Boot Security in Maven deps. And it automatically deny access to unlogged users also for login page if you haven't change rules for it.
So I prefered my own security system and deleted this dependency.🤓
If you want to use Spring Security. You can wrote WebSecurityConfig like this:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserService userService;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf()
.disable()
.authorizeRequests()
//Доступ только для не зарегистрированных пользователей
.antMatchers("/registration").not().fullyAuthenticated()
//Доступ только для пользователей с ролью Администратор
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/news").hasRole("USER")
//Доступ разрешен всем пользователей
.antMatchers("/", "/resources/**").permitAll()
//Все остальные страницы требуют аутентификации
.anyRequest().authenticated()
.and()
//Настройка для входа в систему
.formLogin()
.loginPage("/login")
//Перенарпавление на главную страницу после успешного входа
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/");
}
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder());
}
}
from [https://habr.com/ru/post/482552/] (in russian)
I developed a custom Spring Boot autoconfiguration to ease working with a proprietary messaging library.
The main autoconfiguration class is essentially as follows:
#Configuration
#ConditionalOnClass({LibServer.class, LibClient.class})
#EnableConfigurationProperties(LibProperties.class)
public class LibAutoConfiguration {
#Autowired
LibProperties props;
#Bean
#ConditionalOnMissingBean(LibServer.class)
public LibServer lbServ() {
// create and configure a server object
}
#Bean
#ConditionalOnMissingBean(LibClient.class)
public LibClient lbClient() {
//create and configure a client object
}
}
It seems however that the conditional annotation is not detecting beans declared in the main #SpringBootApplication annotated class.
It only detects beans declared in separate #Configuration annotated classes.
That is to say if I place two #Bean annotated methods returning a LibServer and a LibClient object in the main class I end up with two LibServer and two LibClient objects (the autoconfigured ones and the explicitly declared ones) in the context.
Native spring boot autoconfigurations (such as DataSource one) can instead detect beans declared in the main class too (such as a #Bean annotated jdbcTemplate method).
How do I get proper bean detection even for beans declared in the main class?
Edit
A complete multimodule maven project exhibiting the behaviour is at https://github.com/AlexFalappa/spring-boot-testcase
If you set the log level on debug in you application.properties (logging.level.org.springframework=DEBUG), you will notice that Spring will detect both definitions. However you will also see that the order in which this happens may not be what you expected, because it instantiate beans from the library configuration first, and AFTERWARDS from your main class , and thus you get 2 instances (stripped timestamps to make it friendlier):
Bean definitions
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'autoConfigurationReport'
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for #Bean method af.spring.boot.libbo.LibAutoConfiguration.lbServ()
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.boot.autoconfigure.condition.BeanTypeRegistry'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'autoConfigurationReport'
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for #Bean method af.spring.boot.libbo.LibAutoConfiguration.lbClient()
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for #Bean method af.DemoLibboApplication.libServ()
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for #Bean method af.DemoLibboApplication.libClient()
Bean instantiation
o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'lbServ'
o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'lbServ'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'libAutoConfiguration'
Autoconfiguring LibServer
o.s.b.f.s.DefaultListableBeanFactory : Eagerly caching bean 'lbServ' to allow for resolving potential circular references
o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'lbServ'
o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'lbClient'
o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'lbClient'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'libAutoConfiguration'
Autoconfiguring LibClient
o.s.b.f.s.DefaultListableBeanFactory : Eagerly caching bean 'lbClient' to allow for resolving potential circular references
o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'lbClient'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'lib.CONFIGURATION_PROPERTIES'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store'
o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'libServ'
o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'libServ'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'demoLibboApplication'
o.s.b.f.s.DefaultListableBeanFactory : Eagerly caching bean 'libServ' to allow for resolving potential circular references
o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'libServ'
o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'libClient'
o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'libClient'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'demoLibboApplication'
o.s.b.f.s.DefaultListableBeanFactory : Eagerly caching bean 'libClient' to allow for resolving potential circular references
o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'libClient'
You can also see in the AUTO-CONFIGURATION REPORT that in your current implementation when the conditionals in the LibAutoConfiguration are evaluated, they match and normally it creates the beans:
Positive matches:
-----------------
...
LibAutoConfiguration#lbClient matched
- #ConditionalOnMissingBean (types: af.libbo.LibClient; SearchStrategy: all) found no beans (OnBeanCondition)
LibAutoConfiguration#lbServ matched
- #ConditionalOnMissingBean (types: af.libbo.LibServer; SearchStrategy: all) found no beans (OnBeanCondition)
...
However, if you add the same condition to your main class, you'll see that it will create the beans according to the definitions in LibAutoConfiguration, and when trying to create those for DemoLibboApplication, it will actually find the previously created beans and skip the instantiation:
Negative matches:
-----------------
...
DemoLibboApplication#libClient did not match
- #ConditionalOnMissingBean (types: af.libbo.LibServer; SearchStrategy: all) found the following [lbServ] (OnBeanCondition)
DemoLibboApplication#libServ did not match
- #ConditionalOnMissingBean (types: af.libbo.LibServer; SearchStrategy: all) found the following [lbServ] (OnBeanCondition)
...
You're not importing your LibAutoConfiguration yourself, do you?
This was the hint: your main class is in a parent package from your auto-configuration class. So you're actually importing the #Configuration yourself through component scan. It turns out that when you process that class (via an explicit import rather than via auto-configuration), no beans have been created yet so it does create them. Your application class is processed later and create those beans as well.
If you move the definition somewhere else, it might work (as you have figured out yourself with LibConfig) but that's not deterministic.
TL;DR make sure that your auto-configuration code is in a separate space and is not the target of component scan. I have moved your DemoLibboApplication to the demo package and it worked as expected.
Immediately after creating all the beans declared in the various context files of my application, Spring notifies (see below) that it is destroying singletons and that context initialization failed.
[INFO] Destroying singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory
org.springframework.web.context.ContextLoader [ERROR] Context
initialization failed
Does anyone know why the Spring container is destroying all the beans right after creating them?
NOTE: There are no warnings or errors in the log output aside from the above context initialization failure error -- see below.
[DEBUG] Eagerly caching bean 'uploadService' to allow for resolving potential circular references
2011-09-21 15:19:08 org.springframework.beans.factory.annotation.InjectionMetadata
[DEBUG] Processing injected method of bean 'uploadService': AutowiredFieldElement for private
org.apache.commons.fileupload.disk.DiskFileItemFactory com.faciler.ws.services.UploadService.diskFileFactory 2011-09-21 15:19:08
org.springframework.beans.factory.support.DefaultListableBeanFactory
[DEBUG] Creating shared instance of singleton bean
'diskFileItemFactory' 2011-09-21 15:19:08
org.springframework.beans.factory.support.DefaultListableBeanFactory
[DEBUG] Creating instance of bean 'diskFileItemFactory' 2011-09-21
15:19:08
org.springframework.beans.factory.support.DefaultListableBeanFactory
[INFO] Destroying singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory#b0ede6:
defining beans [org.springframework.beans.
The context initialization failure is causing spring to destroy the beans already successfully created - not the other way round. You will probably need to up the log level to INFO or DEBUG to get to the root cause.
When faced with a situation where you don't know what's causing the issue, remove complexity. In your case, remove most of your beans from the configuration, whether XML or annotation-based. Start adding them back in and see which one breaks the startup cycle. Then you can focus in on why that one bean is causing the failure.
Short answer:
Try increasing JVM memory
here: -XX:PermSize=64m -XX:MaxPermSize=128m -Xms256m -Xmx768m
Detailed answer:
Often Spring desperately destroys beans (hence the communicate) as a way of gaining some memory.
Additionally high Garbage Collector activity slows down spring initialization.
Above I provide settings working for me. Depending on your application complexity you may want to play around with these values.
Disclaimer: It's not always the case. But frequently my spring apps beak down as a result of running them with default JVM memory settings.
Debuging is the best way to find the root cause. If you are using Eclipse for development, run in the debug mode. wait for the control goes to the catch block and in the variables editor you can find the exception object, which should have the stack trace. This way you can find the root cause of the issue.
I have recently faced similar issue. One possible solution to the problem would be to check your main class or wherever you initialize the spring context. Sometimes it happens that exceptions thrown by spring context are caught and never printed or re-thrown. Consider the example below:
AbstractApplicationContext context = null;
try {
context = new ClassPathXmlApplicationContext("beans.xml");
// context.registerShutdownHook();
} catch (Exception e) {
e.printStackTrace();
//print or log error
} finally {
if (context != null) {
context.close();
}
}