Some objects set by #Autowired always null, others are OK - java

I have been working on my first Spring project, and I've come across an annoying problem.
I have a class called 'UsernameService' which is configured as a bean in the dispatcher-servlet.xml:
<bean id="usernameService" class="service.UsernameService" scope="session" >
<aop:scoped-proxy />
</bean>
and when this bean is created in one of my classes (bean definition:)
<bean id="testController" class="controller.TestController" />
as such:
#Autowired
UsernameService uns;
it works absolutely fine. However, when I try and do the same in another class, LogController:
<bean id="logController" class="controller.LogController" />
then it does not work, and I get the following error:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/flexitime] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
I've managed to (I believe) ascribe this error to the fact that uns is never actually set/created and remains as null inside LogController.
I have Googled this extensively and have found many 'solutions', however as yet none of them have worked.
Thanks!
James

Add the auto-wire attribute to your bean:
<bean id="usernameService" class="service.UsernameService" scope="session" autowire="byName">
<aop:scoped-proxy />
</bean>

Related

Spring 4: MethodInvokingFactoryBean on a FactoryBean<> instance

I'm trying to create a FreeMarker configuration in Spring 4 using org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean, and then customising the resulting freemarker.template.Configuration (to change the arithmetic engine).
I'm using the following XML config (simplified):
<bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPaths">...</property>
...
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="freemarkerConfiguration" />
<property name="targetMethod" value="setArithmeticEngine" />
<property name="arguments" value="#{T(freemarker.core.ArithmeticEngine).CONSERVATIVE_ENGINE}" />
</bean>
It works, but I get a lot of warnings during the application startup:
2015-02-27 13:53:03,321 [localhost-startStop-1] [:] WARN support.DefaultListableBeanFactory - Bean creation exception on FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.beans.factory.config.MethodInvokingFactoryBean#0' defined in ServletContext resource [/WEB-INF/spring/freemarker.xml]: Cannot resolve reference to bean 'freemarkerConfiguration' while setting bean property 'targetObject'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'freemarkerConfiguration': FactoryBean which is currently in creation returned null from getObject
My understanding is that it happens because the FreeMarkerConfigurationFactoryBean implements the FactoryBean<> interface. As such, this FactoryBean is "prepared" first, and then FactoryBean.getObject() is called whenever the actual bean it creates (freemarker.template.Configuration) needs to be accessed.
It seems the MethodInvokingFactoryBean gets invoked while the underlying bean is still being "prepared" by FreeMarkerConfigurationFactoryBean, resulting in FreeMarkerConfigurationFactoryBean.getObject() returning null and the method invocation failing.
I suspect I'm getting a lot of warnings because Spring repeatedly tries to invoke the method and fails. At some point the bean produced by the factory is ready, and the method invocation works.
So:
Is my analysis correct?
Why is that happenning? I would think the dependency injection system should detect the dependency between the MethodInvokingFactoryBean and the freemarkerConfiguration, and invoke the method after the factory bean is ready. I tried to add depends-on="freemarkerConfiguration" on the MethodInvokingFactoryBean but it didn't help.
Is there a way to achieve what I want in XML (I can't switch to Java #Configuration right now). Basically I need a way to call freemarker.core.Configurable.setArithmeticEngine() from XML.
Thanks.
After reading some spec I find this, hope is useful for you:
<bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
<property name="freemarkerSettings">
<props>
<prop key="arithmetic_engine">conservative</prop>
</props>
</property>
</bean>
ref: Freemarker Docs
A FactoryBean is supposed to create a bean, not to call a method on a bean! Also the method invoking version will try to create a bean by calling the configured method of the object passed to create a new bean.
What you should look on instead, is the freemarkerSettings property of the FreeMarkerConfigurationFactoryBean and set properties including the arithmetic engine:
<bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPaths">...</property>
<property name="freemarkerSettings">
<map>
<entry key="#{T(freemarker.core.Configurable).ARITHMETIC_ENGINE_KEY}"
value="#{T(freemarker.core.ArithmeticEngine).CONSERVATIVE_ENGINE}"/>
</map>
</property>
...
</bean>

CXF JAXWS Client Creation error - No Such Method

I am trying to create a simple cxf client using the flowing snippet in my spring context:
<jaxws:client id="cxf_client" serviceClass="com.my.service" address="http://my.service.com/">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:client>
However when my server starts I am getting the following exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cxf_client': FactoryBean threw exception on object creation; nested exception is java.lang.NoSuchMethodError: org.apache.cxf.common.util.ReflectionUtil.getDeclaredMethod(Ljava/lang/Class;Ljava/lang/String; [Ljava/lang/Class;)Ljava/lang/reflect/Method;
Does anyone have any idea what is causing my issue, I am using spring 4.0.5 and CXF 3.0.2.
Cheers

Spring Social - Could not generate CGLIB subclass

I am getting the following error when attempting to navigate to the /connect endpoint of the spring social web module.
What I am getting:
[Request processing failed; nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'scopedTarget.connectionRepository'
defined in ServletContext resource [/WEB-INF/appContext.xml]:
Initialization of bean failed; nested exception is
org.springframework.aop.framework.AopConfigException:
Could not generate CGLIB subclass of class
[class org.springframework.social.connect.jdbc.JdbcConnectionRepository]:
Common causes of this problem include using a final class or a non-visible class;
nested exception is java.lang.IllegalArgumentException:
Superclass has no null constructors but no arguments were given]
Relevant portions of web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/appContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Relevant portion of appContext.xml:
<bean id="connectionFactoryLocator"
class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<bean class="org.springframework.social.facebook.connect.FacebookConnectionFactory">
<constructor-arg value="${facebook.clientId}" />
<constructor-arg value="${facebook.clientSecret}" />
</bean>
</list>
</property>
</bean>
<bean id="usersConnectionRepository"
class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository">
<constructor-arg ref="dataSource" />
<constructor-arg ref="connectionFactoryLocator" />
<constructor-arg ref="textEncryptor" />
</bean>
<bean id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg value="#{request.userPrincipal.name}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
Thank you for any responses.
I find this link useful https://github.com/socialsignin/socialsignin-showcase/issues/6, It solved my problem.
Basically in this case problem is with AOP proxy, for some reason CGLIB proxying not working in this case. so you have to turn it off and switch to JDK proxy. So what i did was just make this change in my context.xml -
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true"/>
to
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="false"/>
By making proxy-target-class="false" spring will use JDK proxy (don't ask why i have no idea).
It's solved my problem.
But if it doesn't work for you, then also change this:
<security:global-method-security proxy-target-class="false" >
and this:
<bean id="connectionFactoryLocator" class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<bean class="org.springframework.social.facebook.connect.FacebookConnectionFactory">
<constructor-arg value="xxxxxxxxxxx" />
<constructor-arg value="xxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</bean>
</list>
</property>
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
Hope this helped. Happy coding :)
I had similar issue, however I didn't use any of xml configs, everything was autoconfigured by spring-boot.
Here is what I got trying to do a /connect/facebook:
There was an unexpected error (type=Internal Server Error,
status=500). Error creating bean with name
'scopedTarget.connectionRepository' defined in class path resource
[org/springframework/social/config/annotation/SocialConfiguration.class]:
Initialization of bean failed; nested exception is
org.springframework.aop.framework.AopConfigException: Could not
generate CGLIB subclass of class [class
org.springframework.social.connect.jdbc.JdbcConnectionRepository]:
Common causes of this problem include using a final class or a
non-visible class; nested exception is
org.springframework.cglib.core.CodeGenerationException:
java.lang.reflect.InvocationTargetException-->null
The root cause was having spring-boot-devtools in the classpath. Removing devtools solved the problem. I also found a PR opened by some guy, please leave a comment there to bring more attention to the issue.
pull request
Upd. the PR was merged and starting from 2.0.0.M1 there is no issue with dev-tools anymore.
there is two methods to slove this problem for springboot project:
removing spring-boot-debtools dependency.
setting spring.aop.proxy-target-class=false in your application.properties.
I know this post is very old, however, the exception
Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class ... brought me here.
The solution for me was a default constructor.
The solution for me was to remove final from class definition.
I got the same exception while using PreAuthorize annotation on some Rest Controllers.
The problem was that the controller classes where defined as final and it caused such error.

Spring JDBC : unable to get dataSource

I have a spring XML config file called appConfig.xml which contains a datasource bean and another JDBCtemplate to which datasource is passed as an argument:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
</bean>
<bean id="JDBCTemplate" class="com.myprojects.JDBCTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
I get an error :
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'JDBCTemplate' defined in file [appConfig.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'dataSource' threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
From what I see from this error, it is not able to pass dataSource to JDBCTemplate. The logs also says:
Loaded JDBC driver: com.mysql.jdbc.Driver
I have all dependencies mentioned in pom.xml and I verified that necessary jars for spring are loaded and mysql jdbc connector is also loaded. Any clues on what the issue may be?
I tried a different project where I manually added all spring dependencies and mysql jdbc connector as part of library. It worked fine there. But while trying to include dependencies via pom.xml, I'm facing this issue. So I'm assuming this is to do with some dependency not being pulled in or something. But unable to figure out which one from the error.
It thinks your class JDBCTemplate does not have a property named dataSource
Perhaps you don't have a public method setDataSource() that has a single argument of the right type.
Perhaps it is private.
Perhaps it is spelled wrong.

java.lang.NoClassDefFoundError for my DAO

i am using spring.xml for my controller and dao configuration. my spring-config.xml is as below:
<bean id="courseDao" class="com.platysgroup.lmex.adapter.moodle.dao.CourseDao"
init-method="setMoodleDataSource" depends-on="moodleAuthenticationDetails">
<property name="adapterDataSource" ref="adapterDataSource"></property>
<property name="userDao" ref="userDao"></property>
<property name="announcementDao" ref="announcementDao"></property>
<property name="roleDao" ref="roleDao"></property>
<property name="logDao" ref="logDao"></property>
</bean>
i have a coursedao class in my project in the package com.platysgroup.lmex.adapter.moodle.dao in the project name lmex-impl. but my spring config is not getting the class from a lmex-impl.jar. the spring-config.xml is on lmex-web project. and other thing is that he is showing me a wrong path in exception. the wrong name is Lcom/platysgroup/lmex/adapter/moodle/dao/CourseDao; instead of com/platysgroup/lmex/adapter/moodle/dao/CourseDao; the exception full stacktrace is as below:
javax.servlet.ServletException: Servlet.init() for servlet Spring MVC Dispatcher Servlet threw exception
org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:195)
org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:159)
org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)
org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:417)
root cause
java.lang.NoClassDefFoundError: Lcom/platysgroup/lmex/adapter/moodle/dao/CourseDao;
java.lang.Class.getDeclaredFields0(Native Method)
java.lang.Class.privateGetDeclaredFields(Class.java:2291)
java.lang.Class.getDeclaredFields(Class.java:1743)
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:315)
org.springframework.context.annotation.CommonAnnotation.........
java.lang.ClassNotFoundException: com.platysgroup.lmex.adapter.moodle.dao.CourseDao
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
please help me to resolve this.
Thank you
A NoClassDefFoundError is thrown when the JRE can't find a class. In your case, it can't find the class Lcom/platysgroup/lmex/adapter/moodle/dao/CourseDao, which you most probably did not add to your classpath.
The prefix 'L' indicates the instance of class. Please see Field Descriptors. You should focus on finding issue with configuration of bean courseDao and check that its all dependencies are there in same application context.

Categories

Resources