How to Inject Spring ReloadableResourceBundleMessageSource - spring

In order to programmatically refresh the resource bundle cache, I am using Spring's ReloadableResourceBundleMessageSource. I am having trouble injecting it into my bean where I want to invoke the clearCache() method.
I've had to resort to the following:
private ReloadableResourceBundleMessageSource messageSource;
#Autowired
public void setMessageSource(MessageSource messageSource) {
this.messageSource = (ReloadableResourceBundleMessageSource((DelegatingMessageSource)messageSource).getParentMessageSource();
}
This works, but there must be a better way. The message resource is defined as follows:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" >
<list>
<value>WEB-INF/content/Content</value>
</list>
</property>
</bean>
I don't understand why Spring is injecting a message source of type DelegatingMessageSource.

I don't think that autowiring by type will work in this case, as the autowire candidate will most likely be the ApplicationContext itself (see section 3.8.2 of the reference documentation). This leads to all those layers you have to dig through to get your original ReloadableResourceBundleMessageSource.
Try passing a reference to the messageSource bean via XML configuration instead. Annotating the property with #Qualifier('messageSource') should work as well.

You usually get the DelegatingMessageSource injected when Spring can't find "messageSource" defined. Are you sure you're defining it properly or that it's visible where necessary? I think the problem here is how the XML configuration has been setup.
I had a similar situation with Spring Web Flow and the form action stuff. In my XML configuration the "messageSource" wasn't visible and causing the DelegatingMessageSource to be injected. I placed the "messageSource" bean definition into the webflow configuration and then everything worked and I stopped getting the DelegationMessageSource object. However, this is an ugly fix since now I have "messageSource" defined in two places.
Anyway, this problem only started after I switched to Spring 2.5.6. I'm using Webflow 1. Once I have a chance I will try and update to Webflow 2 and see what happens. Maybe that will fix the issue.

have you tried to define the method as:
public void setMessageSource(ReloadableResourceBundleMessageSource messageSoure) {
this.messageSoure = messageSoure;
}

When you try to run it through messageSource in your controller, you get NOTHING, empty string. And if you look closely, you will find that you have a DelegatingMessageSource in your messageSource property, with an empty parent source, which means it is EMPTY, i.e. always returns blank and this exception occurs in controller
ReloadableResourceBundleMessageSource incompatible with org.springframework.context.support.DelegatingMessageSource
Read more..

Related

Why is Spring 4.0.9 applicationContext initialization getting stuck but not 3.2.1?

My applicationContext initialization was working fine with Spring 3.2.1.
But when I upgraded to 4.0.9 without changing any code or bean definitions), the initialization got stuck. The following statement kept on happening. There's no obvious circular reference though.
Requested bean is currently in creation: Is there an unresolvable circular reference?
I continued to investigate. I deliberately removed a bean definition.
Spring 3.2.1 had the expected outcome: threw a fatal error almost immediately.
Spring 4.0.9 was still getting into this infinite loop, trying to find a different seed bean definition to make things work.
Here's the log statement that kept on happening.
[factory.support.DefaultListableBeanFactory.getTypeForFactoryBean()] - Ignoring bean creation exception on FactoryBean type check:
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'someSeedBean-which-is-different-in-every-instance-of-this-log' defined in the class path resource ........ ;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'someDataSource' is defined
What's changed? Any ideas would be helpful.
Bean definitions that work in both Spring 3.x and 4.x
<bean id="abstractDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" abstract="true" scope="singleton">
<property ....>
</bean>
<bean id="someDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" scope="singleton" parent="abstractDataSource">
<property name="driverClass" .... />
</bean>
<bean id="someSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource"> <ref bean="someDataSource" /> </property>
<property name="packagesToScan"> <list>......</list> </property>
....
Bean definitions that work in Spring 3.x but not in 4.0.9.
#Configuration
public class SomeSpringConfiguration{
// Moving this beanDef to Java for features not available in XML
#Bean(destroyMethod = "close")
public DataSource someDataSource() { // also tried setting this to ComboPooledDataSource
// verified that this beanDefinition is recognized by Spring
// but this bean is never created / this method is never executed
...
return datasource;
}
}
<bean class="SomeSpringConfiguration" />
<bean id="someSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource"> <ref bean="someDataSource" /> </property>
<property name="packagesToScan"> <list>......</list> </property>
....
</bean>
Error I get with Spring 4.0.9 is
Cannot resolve reference to bean 'someSessionFactory' while setting constructor argument;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'someSessionFactory':
Requested bean is currently in creation: Is there an unresolvable circular reference?
Please note that the application has thousands of beans defined in/via xml, #Component, and #Configuration. I had to move above bean from xml to a #Configuration class to execute a complicated bean build procedure.
-----------------------UPDATE
I found the issue: 'tons of MethodInvokingFactoryBean[MIB] usages'. For some reason, Spring 4 was getting confused in presence of tons of MIBs. The exact same code base worked fine with Spring 3. I migrated all the logic performed by various MIBs to an ApplicationListener. Please note that ApplicationListener is not an intended replacement for MIBs but in my case I could reproduce the logic in a listener because the MIBs were just performing static injection of Spring beans into classes not managed by Spring. It not only fixed this issue but decreased Spring startup time to ~200 seconds from ~300 seconds.
Unfortunately, I neither could figure out the root cause in Spring nor could reproduce the issue in a smaller code-base (to share here).
Remove
<bean class="SomeSpringConfiguration" />
from XML, it's already annotated with #Configuration. If it's being scanned it's likely the beans in it are getting created twice. You should move everything into Javaconfig.
Circular references are common during development, when you have a lot of beans and are not careful when you autowire them together. The stacktrace should contain the complete list of beans, telling you where the circular reference starts and ends.
I have never seen random circular references (and I encountered circular references many times over the last 7 years)! As far as I know, the code that builds the dependency tree and instantiates/wire the beans is deterministic. So you should always get the same circular reference every time you run. If you don't, I can only thing of two reasons
There is a bug in the Spring version you are using (I'm 99% sure there is a unit test for this)
You have one of more beans that starts a thread as part of bean instantiation, and the thread uses the applicationContext to load another bean lazily (while the context is still loading).
When I teach Spring classes, I recommend that constructors should only contain field assignments, if you need to start threads (or anything else with a lifecycle) you should use the lifecycle methods. Personally I prefer to implement SmartLifeCycle (over InitializingBean/DisposableBean, #PostConstruct/#PreDestroy), since this ensures that nothing will started until after all beans have been instantiated and wired together.
The core of it is as Strelok says, you are mixing annotations and xml config.
The point of the #Configuration annotation is to avoid xml. When you added the component scan for the package after removing SomeSpringConfiguration from xml.
You would start to create multiples of someDataSource, because it is defined in multiple places (#Bean annotation, and in xml).
Please avoid mixing annotations and xml, only use one of them and stick to that, and this problem will, if not resolved but at least much easier to spot.
If you can create an example project and upload it somewhere I can take a closer look if you are still having this issue.

How to inject spring properties into wicket components?

I'm searching for a possibility to inject a property which is defined in a spring context (provided by a propertiesFactoryBean) into a wicket component. I know the way to inject beans into components by using the #SpringBean-Annotation, but whats the corresponding way for properties?
The way my property is defined:
<bean id="myPropertiesFactory" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="mySpringProperty">mySpringProperty</prop>
</property>
</bean>
Things I've tried. The way it works usually with self defined beans:
#Inject
#Value("${mySpringProperty}")
Using the name of the propertiesFactory to access the property value
#Inject
#Value("$myPropertiesFactory.properties.mySpringProperty")
Using the Value Annotation
#Value("#myPropertiesFactory['mySpringProperty']")
Using SpringBean
#SpringBean(name="myPropertiesFactory.mySpringProperty")
None of these solutions works. So to get mySpringProperty injected i use the workaround to create a bean of the type String which get's injected properly by wicket when i annotate the corresponding member of my component with SpringBean but i think there must be a better solution.
<bean id="mySpringPropertyBean" class="java.lang.String">
<constructor-arg type="java.lang.String" value="https://foobar.com" />
</bean>
Annotate
#SpringBean
private String mySpringPropertyBean;
#SpringBean only supports injection of spring beans. I suppose someone could implement a #SpringValue annotation that does what you want, but as far as I know noone ever did.
What I usually do is:
My wicket application class is a spring bean.
It has properties with #Value annotations - as the object is a spring bean, these are evaluated and set properly
I access the actual values by calling MyApplication.get().getXXX() or ((MyApplication)getApplication()).getXXX()
If the app grows and the number of attributes approach a limit, I refactor them into separate Settings or Config classes - each one a spring bean of it's own, accessible from the application class.
In your Wicket class use instead of #Value("${mySpringProperty}"):
#SpringBean
private PropertiesConfiguration propertiesConfiguration;
Create a new PropertiesConfiguration class:
#Component
public class PropertiesConfiguration {
#Value("${mySpringProperty}")
private String mySpringProperty;
//getters & setters
}
Use in your wicket class:
System.out.println("mySpringProperty=" + propertiesConfiguration.getMySpringProperty());

Injected bean reset to NULL in the Aspect

I am new Spring AOP and Aspectj. I have seen various posts related to injected bean in an aspect being null and I have run into a similar problem. I am still not clear how I should proceed to get past the problem I am currently encountering.
Issue: Currently we are using Spring 3.2.3 and all injection is through Annotation. In my case, the dependent bean is injected properly by Spring but at the point of execution the injected bean is NULL. BTW, this doesn't happen all the time but what I can say is the stack trace when it fails and when it succeeds is slightly different. When the injected bean is not null (I can successfully use the injected bean service), the call to the before advice (in the aspect) always happens before the target method is called as it should.When the injected bean is NULL, the call to the aspect is from the first statement of the target method. At this point, I think another aspect is instantiated and has no reference to the injected bean. Here is the aspect I have created:
#Component
#Aspect
public class Enable{
private NameService nameService;
#Autowired
public void SetNameService(NameSerice service){
// service is injected properly
this.nameSerice = service;
}
#Before("* *.*(..)")
public void callBefore(JoinPoint jp){
//sometimes nameService is null and sometimes it not not
this.nameService.lookup(...);
}
}
Examining the various posts, one way to get around this (as suggested in the post) is to configure the aspect in the XML configuration file and use the factory-method ="aspectOf" and in the configuration inject the reference to the NameService bean as a property. Our whole project uses Annotation based injection (as stated earlier). Assuming I can still configure the above aspect in an XML configuration file, how can I get the reference NameService bean Id so that I can add it to the configuration. I also saw a post related to using Configurable annotation but I assume that is for objects created outside the Spring IOC.
Currently, the aspects are woven using Aspectj compile option in pom.xml. Our root-context.xml contains the entry context:annotation-config and the aspect is injected into Spring IOC because component-scan is turned on for the folder where the aspect resides. Any help will be appreciated
This is well common error when use aspects in spring, you should add
<context:spring-configured/>
and
<aop:aspectj-autoproxy />
also add
#Configurable
#Aspect
public class Enable
To your appContext.xml
aspectOf is another style to do the above but I prefer use the nature of context.
It might be too late to answer this question. But i have come across the same situation and i fixed it as below.
1) Have a setter and getter for "NameService" in your aspect class.
2) Mark "NameService" with #Component ("nameService")
3) Configure "nameService" in xml configuration using setter injection.
4) Re-Start your server after making changes.
This should resolve the problem of getting null for "NameService" in aspect.

How to wire a SessionFactory into a Hibernate Interceptor with Spring? [duplicate]

I want to declare two beans and instantiate them using Spring dependency injection?
<bean id="sessionFactory" class="SessionFactoryImpl">
<property name="entityInterceptor" ref="entityInterceptor"/>
</bean>
<bean id="entityInterceptor" class="EntityInterceptorImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
But Spring throws an exception saying "FactoryBean which is currently in creation returned null from getObject"
Why is inter-dependent bean wiring not working here? Should i specify defferred property binding anywhere?
Unfortunately the way container initialization works in Spring, a bean can only be injected in another bean once it is fully initialized. In your case you have a circular dependency that prevents either bean to be initialized because they depend on each other. To get around this you can implement BeanFactoryAware in one of the beans and obtain the reference to the other bean using beanFactory.getBean("beanName").
neesh is right, Spring doesn't do this out of the box.
Interdependent beans hint at a design problem. The "clean" way to do this is to redesign your services in such a way that there are no such odd dependencies, of course provided that you have control over the implementations.
You can implement a BeanPostProcessor that sets the dependency.
Or...
See Costin's reply here:
http://forum.springframework.org/showthread.php?t=19569&highlight=circular+dependencies
See Andreas' reply here:
http://forum.springframework.org/showthread.php?t=29572&highlight=circular+dependencies
you can extend the ApplicactionContext that are using and override the method createBeanFactory()
protected DefaultListableBeanFactory createBeanFactory(){
DefaultListableBeanFactory beanFactory = super.createBeanFactory();
// By default this is false;
beanFactory.setAllowRawInjectionDespiteWrapping( true );
return beanFactory;
}
This works, but be careful because this allows circular references.

Spring 3.0.5 doesn't evaluate #Value annotation from properties

Trying to auto-wire properties to a bean in Spring 3.0.5.RELEASE, I'm using:
config.properties:
username=myusername
main-components.xml:
<context:property-placeholder location="classpath:config.properties" />
MyClass:
#Service
public class MyClass {
#Value("${username}")
private String username;
...
}
As a result, username gets set to literally "${username}", so the expression doesn't get parsed. My other auto-wired dependencies on this class get set, and Spring doesn't throw any exception. I also tried to add #Autowired but it didn't help.
If I parse properties to a separate bean and then use #Autowired + #Qualifier, it works:
<bean id="username" class="java.lang.String">
<constructor-arg value="${username}"/>
</bean>
Any ideas how to use just #Value? Maybe I need to include some Spring dependency that I haven't? Thank you
Found what the issue was. Copy/paste from comments:
Are you sure you have <context:property-placeholder> in the same application context as your MyClass bean (not in the parent context)? – axtavt
You're right. I moved <context:property-placeholder> from the context defined by the ContextLoaderListener to the servlet context. Now my values get parsed. Thanks a lot! - alex

Resources