Autowiring fails IllegalArgument un-safe operation exception - spring

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"/>

Related

Unable to create retry-able datasource for spring boot jdbc

I would like to add the retry feature for database connection certain number of times until the app acquires it. For the I have used the spring-retry on the DataSource but it is not working. It is throwing the following error
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jdbcTemplate' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/JdbcTemplateConfiguration.class]: Unsatisfied dependency expressed through method 'jdbcTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: ExistingValue must be an instance of com.zaxxer.hikari.HikariDataSource
I have seen the debug logs but those are not helpful. Here is the sample source code . kindly help
Note: the dependencies mentioned in build.gradle is required for my app. I have only extracted the retry part.
Your use-case is delaying the start of Spring Boot until your database is up. Spring actually ships with a component that does that. The DatabaseStartupValidator is that component and has existed since about Spring 1.x.
You can add it as a bean and it will wait for further bootstrapping until the database is up.
#Bean
public DatabaseStartupValidator databaseStartupValidator(DataSource dataSource) {
var dsv = new DatabaseStartupValidator();
dsv.setDataSource(dataSource);
return dsv;
}
For a more detailed explanation see this blog post of mine.

java version "1.8.0_121" Requested bean is currently in creation: Is there an unresolvable circular reference?

When I build and deploy my spring based Application with
java version "1.8.0_112" it compiles and deploys fine.
Also, if i compile with java version "1.8.0_121", and deploy with
java version "1.8.0_112" that works too.
But when I compile and deploy the same Application with
java version "1.8.0_121"
it gives me an error for one service:
Error creating bean with name 'namesServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private a.b.c.backend.services.account.PersonService a.b.c.backend.services.serviceimpl.NamesServiceImpl.personService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CISExpressionHandler' defined in URL
[jar:file:/usr/local/tomcat7-7/webapps/ServicesApp/WEB-INF/lib/E2Services.jar!/META-INF/spring/applicationContext-security.xml]: Cannot resolve reference to bean 'CISPermissionEvaluator' while setting bean property 'permissionEvaluator'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'CISPermissionEvaluator': Requested bean is currently in creation: Is there an unresolvable circular reference?
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private a.b.c.backend.services.ciscase.CaseService a.b.c.backend.services.security.permissionEvaluators.CaseOwnerPermission.caseService; nested exception is org.springframework.beans.factory.BeanCreationException
One explanation, I could find was:
The exception may or may not occur depends on the creation order of beans. We load them with config something like below in web.xml
(/usr/local/tomcat7-7/webapps/ServicesApp/WEB-INF/web.xml)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
The XML files will be loaded by XmlWebApplicationContext class and the loading order of files are not guaranteed.
It just loads files from the file system. The problem is here.
There's no problem if the class loads the application context file first, because your beans are already created when they are used for the construction injection of Spring Security. But, if it loads the Spring Security context file first, the circular reference problem occurs, because Spring tries to use your beans in the constructor injection before they had been created.
How to solve the problem?
Force the loading order of the xml files. loading the security context xml file at the end of the application context file by using
<import resource="applicationContext-security.xml">.
Now how this got introduced with JDK version change? I don't have an explanation for that
ref: Splitting applicationContext to multiple files
Q: How do i get the order of beans at deployment ?

Struts 2 action method intercepting using Spring AOP

I'm trying to intercept the Struts2 Action class's methods to print the method start and method end indication statement using Spring AOP.
The fact is , my Struts2 actions instance are also Spring beans (Struts2 and Spring integration done as per the url: http://www.mkyong.com/struts2/struts-2-spring-integration-example/). AOP configurations is as below:
<bean id="testAdviceBean" class="com.tcs.oss.plugins.SimpleAdvice">
</bean>
<aop:config>
<aop:aspect ref="testAdviceBean" order="200">
<aop:pointcut id="testPoint2"
expression="execution(java.lang.String com.test..DeviceAction.*(..))"
/>
<aop:around pointcut-ref="testPoint2" method="loggingAdvice" />
</aop:aspect>
</aop:config>
In the advice method loggingAdvice , I'm trying to print the method START and method END statement using the ProceedingJoinPoint API.The advice method is not called at all ... instead it's ending up with the error below after going through the struts default interceptor chain ...
But I'm getting the below ERROR TRACE:
09:26:49,093 TRACE
[org.springframework.beans.factory.support.DefaultListableBeanFactory]
(http-01h3463916-172.20.211.235-8543-5) Ignoring constructor [public
org.apache.struts2.dispatcher.ServletDispatcherResult(java.lang.String)]
of bean 'org.apache.struts2.dispatcher.ServletDispatcherResult':
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name
'org.apache.struts2.dispatcher.ServletDispatcherResult': Unsatisfied
dependency expressed through constructor argument with index 0 of type
[java.lang.String]: : No matching bean of type [java.lang.String]
found for dependency: expected at least 1 bean which qualifies as
autowire candidate for this dependency. Dependency annotations: {};
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
matching bean of type [java.lang.String] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for
this dependency. Dependency annotations: {}
09:26:49,095 TRACE
[org.springframework.beans.factory.support.DefaultListableBeanFactory]
(http-01h3463916-172.20.211.235-8543-5) Not autowiring property
'urlHelper' of bean
'org.apache.struts2.dispatcher.ServletDispatcherResult' by name: no
matching bean found
09:26:49,100 DEBUG
[org.apache.struts2.dispatcher.ServletDispatcherResult]
(http-01h3463916-172.20.211.235-8543-5) Forwarding to location
/General/error.jsp
If I just remove the above AOP configurations, It's just working fine. What I'm doing wrong ?
The advice method is not called because Action class was extending from ActionSupport class which in turn has a interface implementations... So , in this case, A JDK proxy was created for the Action class -- This type of proxy doesn't have any method specific(non-inheritance) to the Action class.
Adding proxy-target-class="true" attribute, in the AOP configuration, made the Spring to generate CGLib(need to add CGLib in the Classpath) based proxy.. which now has the non-inheritance methods too, of the Action class.
After a bunch of digging, I think I found the issue (if you're using Spring to help with AOP, even if you're not you're probably going to need a different ObjectFactory), long and short of it is that you need to make sure that the struts ObjectFactory is setup properly:
<constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>
or
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>
source: http://www.javawebdevelop.com/3294124/

need to understand autowiring beans in spring mvc project?

In my spring mvc+hibernate+annotations project I have these three classes
UserServiceImpl.java
#Service("userService")
public class UserServiceImpl implements UserService {
#Autowired
private UserDAO userDAO;
//other codes
}
UserDAOImpl.java
#Repository("userDAO")
public class UserDAOImpl implements UserDAO {
#Autowired
private SessionFactory sessionFactory;
//other codes
}
RegistrationController.java
#Controller
#RequestMapping("/registration.htm")
public class RegistrationController {
#Autowired
private UserService userService;
//other codes
}
In my dispatcher-servlet.xml I have added the following
<context:annotation-config />
<context:component-scan base-package="com.alw.controllers,com.alw.DAOs,com.alw.services" />
and
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
When I run the project I got the following exceptions:
Error creating bean with name 'registrationController':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private com.alw.services.UserService
com.alw.controllers.RegistrationController.userService;
AND
Error creating bean with name 'sessionFactory' defined in ServletContext resource
[/WEB-INF/dispatcher-servlet.xml]:
Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError:
org/apache/commons/pool/impl/GenericObjectPool
CAN SOMEBODY POINT OUT THE WHERE I AM MISSING ?
THIS HAS TAKEN MY ENTIRE DAY TODAY.
EDIT:
I added commons.pool but no result.
I have these set of exceptions.
Error creating bean with name 'registrationController':
Error creating bean with name 'userService':
Error creating bean with name 'userDAO':
Error creating bean with name 'sessionFactory' defined in ServletContext
resource [/WEB-INF/dispatcher-servlet.xml]:
Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError:
Could not initialize class org.hibernate.cfg.AnnotationConfiguration
THANKS....
As duffymo points out, you're missing commons pool from your classpath. As for the other problem, when you say you get error 1 and error 2, do you mean you get two, unrelated errors at different times, or do you get error 1 caused by error 2. If you're seeing them both in the log at the same time, they're probably the same thing, where the second is the cause of the first.
On the other hand, you're making the common mistake of putting all of your service beans into the context belonging to the DispatcherServlet. If you're also declaring the beans in the root context, that could be causing problems for you, too. See this other answer and its linked answers to understand the difference between the root and child contexts in a Spring MVC app:
Why DispatcherServlet creates another application context?
Especially:
Spring-MVC: What are a "context" and "namespace"?
The second one is easy: you're missing the JAR that contains org.apache.commons.pool.impl.GenericObjectPool in your CLASSPATH.
The question is: which class loader? The Java EE app server has a hierarchy of class loaders. I'm guessing that you want to add that JAR to your server /lib directory so it'll be available when the connection pool is set up.
The first one is not clear to me. Try changing your base package to "com.alw" and see if that sorts it out.

Lazy init not honored for JmsTemplate

We are developing a Spring-based application that utilizes JMSTemplate to send/receive JMS messages to/from the Tibco EMS Server.
With the current implementation, during the TomCat start up the project fails if the EMS Server is down. This is because in the Spring config file, we have JMS related beans that are trying to connect to the EMS server.
So, one solution is to make all JMS related beans initiate only when they are required (and not during the start up). For that we set all the JMS related beans' lazy-init attribute to true.
An excerpt:
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager" lazy-init="true">
<property name="internalJmsQueueConnectionFactory"> <ref bean="jmsQueueConnectionFactory" />
</property>
</bean>
<bean id="jmsTemplateWithClientAcknowledge" class="org.springframework.jms.core.JmsTemplate" lazy-init="true">
<property name="internalJmsQueueConnectionFactory" ref="jmsQueueConnectionFactory"/>
</bean>
Here's the problem: if we set lazy-init="true" ONLY on jmsTransactionManager bean, the project loads fine without problems. However, as soon as we set lazy-init="true" on the jmsTemplateWithClientAcknowledge bean as well, the project fails. Same failure reason: couldn't connect to the EMS Server.
The error from the log:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsMsgSenderImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jms.core.JmsTemplate com.cv.pub.engine.service.impl.JmsMsgSenderImpl.jmsTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplateWithClientAcknowledge' defined in ServletContext resource [/WEB-INF/spring/jms-context.xml]: Cannot resolve reference to bean 'internalJmsQueueConnectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'internalJmsQueueConnectionFactory' defined in ServletContext resource [/WEB-INF/spring/jms-context.xml]: Cannot resolve reference to bean 'targetJmsQueueConnectionFactory' while setting bean property 'targetConnectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'targetJmsQueueConnectionFactory' defined in ServletContext resource [/WEB-INF/spring/jms-context.xml]: Invocation of init method failed; nested exception is javax.naming.ServiceUnavailableException: Failed to query JNDI: Failed to connect to the server at tcp://localhost:7222 [Root exception is javax.jms.JMSException: Failed to connect to the server at tcp://localhost:7222]
I will greatly appreciate your thoughts and help!
Is targetJmsQueueConnectionFactory being used by internalJmsQueueConnectionFactory? According to the log it appears to be like that. You will need to make internalJmsQueueConnectionFactory also lazy-init.

Resources