Spring and hibernate integration - spring

I am doing spring and hibernate integration example getting the below exception. Please advise me how to solve it.
log4j:WARN No appenders could be found for logger (org.springframework.beans.factory.xml.XmlBeanDefinitionReader).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'd' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:509)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1041)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:273)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at com.javatpoint.InsertTest.main(InsertTest.java:14)

You will have to share some code snippets before someone can actually help you here!
Looking at the exception it seems you have created a Class property "d" and marked it as #Autowired.
Spring is trying to find a class of type d or name d registered in its context.
You register a class by using #Service or #Component etc annotation.
Update:(after the OP's comment).
Please ensure you are creating d bean using below code in application context.
<bean id="d" class="com.javatpoint.EmployeeDao">
<property name="template" ref="template"></property>
</bean>

Related

Application Context returns instance of org.quartz.impl.StdScheduler instead of org.springframework.scheduling.quartz.SchedulerFactoryBean

I am trying to use quartz scheduler with spring and trying to create bean of SchedulerFactoryBean, I have added below entry in spring bean xml but it always returns StdScheduler instance instead of SchedulerFactoryBean.
<beans:bean id="corescheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" scope="prototype" lazy-init="true" destroy-method="destroy">
I am getting below error when getting a bean from application context.
SchedulerFactoryBean coreScheduler = (SchedulerFactoryBean) applicationContext.getBean("corescheduler");
Error:
org.quartz.impl.StdScheduler cannot be cast to org.springframework.scheduling.quartz.SchedulerFactoryBean
Can anyone please help ?
That is a perfectly normal behavior. Please check Spring docs to see how Spring factory beans work in general.
See https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html#getObject-- and you will find out this factory bean creates and returns org.quartz.Scheduler instances.

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.

Autowiring fails IllegalArgument un-safe operation exception

I am getting the following exception after upgrading my Spring jars.
org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.transformer.HeaderEnricher#4': Cannot create inner bean '(inner bean)' of type [org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor] while setting constructor argument with key [#{partnerHeaderKey}]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#19': Injection of resource dependencies failed; nested exception is java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at org.springframework.beans.factory.support.BeanDefinitionValue Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#19': Injection of resource dependencies failed; nested exception is java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:271)
... 40 more
Caused by: java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:57)
at java.lang.reflect.Field.set(Field.java:657)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
... 44 more
From what I have read I needed to add #Component annotation to my bean and/or create the in my application context - neither of these approaches have worked. The DAO it is referring to is declared like so <bean id="partnerDAO" class="com.follett.fheg.coursemateriallookup.coursematerial.data.dao.impl.PartnerDAOImpl"/>. If I remove the #Component annotation I get a red line under #Autowired and a message that says "Autowired members must be defined in the valid spring bean (#Component/#Service etc..)", but after doing that i still get the errors.
I am using Spring integration so the bean to auto-wire is defined there.
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner">
<bean class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher"/>
</integration:header>
</integration:header-enricher>
Any thoughts or help is appreciated! Thank you.
Note: the application runs fine if I drop back down to Spring 2.1.4.RELEASE even without declaring the #Component or <bean> in the application context.
UPDATE
As blackpanther mentions below I need a element in the application context. I failed to mention that I DO Have this <context:component-scan base-package="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher" /> There is another for the DAO's as well <context:component-scan base-package="com.follett.fheg.coursemateriallookup.coursematerial.data.dao" />
Not exactly, just putting the annotation #Component does not mean that that Java class will have it's properties autowired. In order to use the #Component annotation effectively, you must tell Spring where to look for these classes. This is done by the <context:component-scan base-package="package.name" /> tag in your Spring configuration.
I would have a look at this article as it may help you.
You can specify #Qualifier on top of the bean declaration inside the component like below.
#Autowired
#Qualifier("loginService")
private ILoginService loginService;
loginService is the name of the bean in the .xml context file.
I was able to resolve this issue by using #Component annotation as well as modifying the way the beans were created in the context.
For some reason when I moved the <bean class=""> out of the <integration:header> and added a ref-"" attribute it started working just fine. I am getting a different error, but I was able to get the application running.
old way
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner">
<bean class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.Partner HeaderEnricher"/>
</integration:header>
</integration:header-enricher>
new way
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner" ref="myBean">
</integration:header>
</integration:header-enricher>
</integration:chain>
<bean id="myBean" class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher"/>

Reference an Annotated Spring Component in an XML Bean Definition

I am using an external library that requires that I configure it using an XML Bean definition; in the Bean definition I need to provide an external class with a Bean from my project. I am using spring annotations with component scanning.
How do I reference my annotated Bean within the XML Bean Definition?
Are there any alternatives to creating an XML Bean Definition?
Details: Spring 3.0.7
No matter how it got created (based on XML- or annotation- metadata), every bean ends up in the application context under a unique name.
If you've just annotated your class with #Component or derivatives, without stating any name, the default naming scheme will be applied and the bean name will be your class name with the first character lowercased: ClassName => "className".
With that in mind, if you need to inject that bean in an XML bean definition, you do it like with any other bean in your context:
<bean id="someBean" class="SomeClass">
<property name="someProp" ref="className"/><!-- to stick to the above example -->
</bean>
Since you're mixing annotations with XML, the application context will be able to locate the "className" bean properly.
The #Service annotation takes an optional String value which can be used to give the bean a name of your choosing. For example, if your custom bean looks like:
#Service("mySpecialName")
public class MyClass { ... }
Then your xml could have:
<bean class="com.someone.else.library.SomeClass">
<property name="someProp" ref="mySpecialName"/>
</bean>
Make sure add below code in your xml file
<context:component-scan base-package="" />
<context:annotation-config />

How to import Java-config class into XML-config so that both contexts have beans?

I have a project where I need to bootstrap #Configuration java-config classes into the XML configuration.
To do that, I'm reading that I also need to include the following bean definition (along with the bean definitions of the classes annotated with #Configuration).
<bean class="org.springframework.config.java.process.ConfigurationPostProcessor" />
But, I end up receiving the following error:
Caused by: java.lang.ClassNotFoundException: org.springframework.config.java.process.ConfigurationPostProcessor
I have to assume I'm missing a jar somewhere, but my various web searches hasn't resulted in an answer yet. Any help would be greatly appreciated. Thanks.
EDIT: Evidently, I was reading old documentation, which is no longer current. Let me back up. My project contains older XML-based configuration. The newer code is all using 'Java-config'. With that said, the contexts are apparently completely separate. I'd like to 'import' a java-config class into the XML configuration, so that both contexts have those particular beans. Does anyone know how I can do that?
This actually ended up being fairly simple. To get a Java-config bean definition into the xml-config, simply define the Java-config class as a bean within the XML-config. There are no extra jars necessary.
#Configuration
public class SomeJavaConfig {
#bean
... [bean definition]
}
inside the XML-config, you define this class as a bean.
<!-- needed to pick up the annotated java-config -->
<context:annotation-config />
<!-- Importing java-config class, which are annotated with #Configuration -->
<bean name="SomeJavaConfig" class="[fully qualified path].SomeJavaConfig" />
The XML-config, which may be part of a different context, now has all the bean definitions defined within the JavaConfig class.
UPDATED - to included Alan Franzoni's comment below in the answer.
Alternatively to annotation-config you can use component-scan. Then you do not have to include the Configuration Bean in XML:
<context:component-scan base-package="[fully qualified package path]" />
See Difference between <context:annotation-config> vs <context:component-scan> for more details.
Should be in:
spring-javaconfig-<version>.jar

Resources