Why is Spring Container Destroying Beans Immediately After Creating Them? - java

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();
}
}

Related

sql scripts not working when JobRegistryBeanPostProcessor bean is used

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.

Spring CLI command not found?

I have a superclass which implements CommandMarker. Some children appears as an usable command, but this one does not.
The log says:
10:29:01.128 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'abortCommand'
....
10:29:01.230 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'abortCommand'
I found no errors while creating the bean, but when I try to use the command I get
Command 'abort' not found (for assistance press TAB)
I tagged the corresponding method with #CliCommand(value = "abort", help = "blah")
Seems that a method tagged with #CliCommand must be public to be visible for spring, tagging the class as #Component is not sufficient.

Java Batch(JSR-352) and Session Context CDI

I am using the java Batch (JSR-352), it is possible to work with a session bean inside it? I needed to have a Bean with #SessionScope annotation, to catch some information in it, that to differentiate the type of User that is running the batch process.
It's possivel use a Session Context CDI inside the specification ? If is possible how is the best pratice
In general, the session isn't going to propagate from the thread starting the job via JobOperator to the execution thread. I don't recall if this is under discussion in the CDI specification still or a settled matter, but for now you can't.

Spring default-lazy-init does not seems to work, i see Pre-instantiating of singletons

I am defining default-lazy-init="true" in the spring context file inside beans tag but when I start tomcat, I see my beans are getting instantiated. here is what it shows in log -
org.springframework.beans.factory.support.DefaultListableBeanFactory (DefaultListableBeanFactory.java:555) - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#ac6fb1: defining beans [dataSource,my other beans in app.......
Am I missing something ?
Even if a bean is declared to be lazy initialized, it will still be initialized if another bean depends on it.
I'm going to assume from your log, that the bean in question is dataSource. I will also assume you have other beans that depend on dataSource (otherwise it wouldn't be very useful). If the context initializes the other beans and finds that, for example, it needs to autowire the dataSource bean, it will have to first initialize it.
If you want full lazy initialization, you will have to make every bean in some object graph be lazily initialized.

How to find out how a specific bean is wired in Spring

I have a spring application (A) which uses a transient dependency (B) which in itself is based on Spring as well.
So to summarize, war A & jar B are both spring projects. B is a dependency of A.
One of the attributes of a class in B is decorated in the following way
#Resource(name="thisIsTheTargetRef")
private String hardToFindMe;
I went through the application context files of A & B but I do not find a declaration of a bean with the id 'thisIsTheTargetRef'. But somehow the logs show that the .hardToFindMe. attr gets wired with 'thisIsTheTargetRef' bean. I search through both the A & B projects including all other dependencies to see if this is getting picked up from somewhere else. No dice. I even inspected the Component-scan packages but with no luck. I also did a hard text search for 'thisIsTheTargetRef' in both A & B including the dependency projects. I still don't find it.
Here is a log snippet showing that the bean is still getting wired.
[#|2014-01-27T18:23:16.654+0000|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=10;_ThreadName=Thread-3;|77875 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory {} null - Returning cached instance of singleton bean 'thisIsTheTargetRef'
|#]
[#|2014-01-27T18:23:46.640+0000|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=10;_ThreadName=Thread-3;|18:23:46,639 INFO [XmlWebApplicationContext:1332] Bean 'thisIsTheTargetRef' of type [class org.springframework.jndi.JndiObjectFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
|#]
It does appears that I'm missing something here. There might have been a dependency that I have missed looking into and my eyes are just fooling me. But any other obvious places that I should look at?
If not, based on the logs, XmlWebApplicationContext:1332 is referred as the location for the bean. How can I debug to find out where it is getting picked from? Thanks.
You might be lucky by defining a watch/breakpoint on the field you know where it is injected. During the debugging you should get a stop during the autowiring process and you will see which class is wired. This should help identifing it and then check occurences for this class.
I'm not sure if you can directly find out from where this bean is loaded. One hint should be either the annotationprocessor or xmlprocessor.

Categories