java - Problems with Autowired and Spring Injection -
this question has answer here:
- why spring @autowired field null? 10 answers
solved
lately i've been having problems spring mvc application i'm trying develop. main problem don't know why @autowired annotation not working , that's because have wrong. i'm going post here code can me issue! lot guys:
web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>helloworld application</display-name> <description> simple web application source code organization based on recommendations of application developer's guide. </description> <servlet> <servlet-name>webdispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>webdispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <filter> <filter-name>springsecurityfilterchain</filter-name> <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class> </filter> <filter-mapping> <filter-name>springsecurityfilterchain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web.context.contextloaderlistener</listener-class> </listener> <context-param> <param-name>contextconfiglocation</param-name> <param-value> /web-inf/applicationcontext.xml </param-value> </context-param> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
applicationcontext.xml
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <context:annotation-config /> <context:spring-configured /> <context:component-scan base-package="com.agrichem.server" /> <bean id="messagesource" class="org.springframework.context.support.reloadableresourcebundlemessagesource"> <property name="basename" value="classpath:messages" /> <property name="defaultencoding" value="utf-8" /> </bean> <bean id="propertyconfigurer" class="org.springframework.beans.factory.config.propertyplaceholderconfigurer" p:location="web-inf/jdbc.properties" /> <bean id="datasource" class="org.apache.commons.dbcp.basicdatasource" destroy-method="close" p:driverclassname="${jdbc.driverclassname}" p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" /> <bean id="sessionfactory" class="org.springframework.orm.hibernate4.localsessionfactorybean"> <property name="datasource" ref="datasource" /> <property name="configlocation"> <value>classpath:hibernate.cfg.xml</value> </property> <property name="hibernateproperties"> <props> <prop key="hibernate.dialect">${jdbc.dialect}</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <tx:annotation-driven /> <bean id="transactionmanager" class="org.springframework.orm.hibernate4.hibernatetransactionmanager"> <property name="sessionfactory" ref="sessionfactory" /> </bean> <bean id="securitydao" class="com.agrichem.server.model.repositories.impl.securitydaoimpl"> </bean> </beans>
webdispatcher-servlet.xml
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <context:annotation-config /> <context:spring-configured /> <context:component-scan base-package="com.agrichem.server" /> <bean id="viewresolver" class="org.springframework.web.servlet.view.urlbasedviewresolver"> <property name="viewclass" value="org.springframework.web.servlet.view.jstlview"/> <property name="prefix" value="/views/"/> <property name="suffix" value=".jsp"/> </bean> <!-- <import resource="spring-security-web.xml"/> --> </beans>
securitydao.java
public interface securitydao { public boolean validateuser(user user); public user authenticateuser(user user); public user getuser (user user); }
securitydaoimpl.java
@repository("securitydao") public class securitydaoimpl extends hibernatedao implements securitydao { public securitydaoimpl() { super(); } @override public boolean validateuser(user user) { query query = opensession() .createquery( "from user u u.login = :login , u.password = :password"); query.setparameter("login", user.getlogin()); query.setparameter("password", user.getpassword()); return (query.list().size() > 0) ? true : false; } @override public user authenticateuser(user user) { query query = opensession() .createquery( "from user u u.login = :login , u.password = :password"); query.setparameter("login", user.getlogin()); query.setparameter("password", user.getpassword()); return (user) query.uniqueresult(); } @override public user getuser(user user) { query query = opensession().createquery( "from user u u.login = :login"); query.setparameter("login", user.getlogin()); return (user) query.uniqueresult(); } }
websecurityconfig.java
@configuration @enablewebmvcsecurity public class websecurityconfig extends websecurityconfigureradapter { @autowired public void configureglobal(authenticationmanagerbuilder auth) throws exception { auth.userdetailsservice(new customuserdetailsservice()); } @override protected void configure(httpsecurity http) throws exception { http.csrf().disable(); http.authorizerequests().antmatchers("/home/logout.do").permitall() .anyrequest().authenticated().and().formlogin() .loginpage("/home/login.do").permitall() .failureurl("/home/accessdenied.do").permitall(); } }
customuserdetailsservice.java
@configurable @transactional public class customuserdetailsservice implements userdetailsservice { @autowired @qualifier("securitydao") private securitydao securitydao; @override public userdetails loaduserbyusername(string arg0) throws usernamenotfoundexception { com.agrichem.server.model.security.user user = securitydao .getuser(new com.agrichem.server.model.security.user(arg0, "")); user userdetails = new user(user.getlogin(), user.getpassword(), getgrantedauthorities(user.getroles())); return userdetails; } public static list<grantedauthority> getgrantedauthorities(set<role> roles) { list<grantedauthority> authorities = new arraylist<grantedauthority>(); (role role : roles) { authorities.add(new simplegrantedauthority(role.getname())); } return authorities; } public securitydao getsecuritydao() { return securitydao; } public void setsecuritydao(securitydao securitydao) { this.securitydao = securitydao; } }
in point when try login application , i'm gonna check dao access database i'm getting 'securitydao' property null. in customuserdetailsservice in following line : com.agrichem.server.model.security.user user = securitydao.getuser(new com.agrichem.server.model.security.user(arg0, "")); , obvisously i'm getting nullpointerexception.
org.springframework.security.authentication.internalauthenticationserviceexception @ org.springframework.security.authentication.dao.daoauthenticationprovider.retrieveuser(daoauthenticationprovider.java:110) @ org.springframework.security.authentication.dao.abstractuserdetailsauthenticationprovider.authenticate(abstractuserdetailsauthenticationprovider.java:132) @ org.springframework.security.authentication.providermanager.authenticate(providermanager.java:156) @ org.springframework.security.authentication.providermanager.authenticate(providermanager.java:177) @ org.springframework.security.web.authentication.usernamepasswordauthenticationfilter.attemptauthentication(usernamepasswordauthenticationfilter.java:94) @ org.springframework.security.web.authentication.abstractauthenticationprocessingfilter.dofilter(abstractauthenticationprocessingfilter.java:211) @ org.springframework.security.web.filterchainproxy$virtualfilterchain.dofilter(filterchainproxy.java:342) @ org.springframework.security.web.authentication.logout.logoutfilter.dofilter(logoutfilter.java:110) @ org.springframework.security.web.filterchainproxy$virtualfilterchain.dofilter(filterchainproxy.java:342) @ org.springframework.security.web.header.headerwriterfilter.dofilterinternal(headerwriterfilter.java:57) @ org.springframework.web.filter.onceperrequestfilter.dofilter(onceperrequestfilter.java:107) @ org.springframework.security.web.filterchainproxy$virtualfilterchain.dofilter(filterchainproxy.java:342) @ org.springframework.security.web.context.securitycontextpersistencefilter.dofilter(securitycontextpersistencefilter.java:87) @ org.springframework.security.web.filterchainproxy$virtualfilterchain.dofilter(filterchainproxy.java:342) @ org.springframework.security.web.context.request.async.webasyncmanagerintegrationfilter.dofilterinternal(webasyncmanagerintegrationfilter.java:50) @ org.springframework.web.filter.onceperrequestfilter.dofilter(onceperrequestfilter.java:107) @ org.springframework.security.web.filterchainproxy$virtualfilterchain.dofilter(filterchainproxy.java:342) @ org.springframework.security.web.filterchainproxy.dofilterinternal(filterchainproxy.java:192) @ org.springframework.security.web.filterchainproxy.dofilter(filterchainproxy.java:160) @ org.springframework.web.filter.delegatingfilterproxy.invokedelegate(delegatingfilterproxy.java:344) @ org.springframework.web.filter.delegatingfilterproxy.dofilter(delegatingfilterproxy.java:261) @ org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:243) @ org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:210) @ org.apache.catalina.core.standardwrappervalve.invoke(standardwrappervalve.java:222) @ org.apache.catalina.core.standardcontextvalve.invoke(standardcontextvalve.java:123) @ org.apache.catalina.authenticator.authenticatorbase.invoke(authenticatorbase.java:502) @ org.apache.catalina.core.standardhostvalve.invoke(standardhostvalve.java:171) @ org.apache.catalina.valves.errorreportvalve.invoke(errorreportvalve.java:100) @ org.apache.catalina.valves.accesslogvalve.invoke(accesslogvalve.java:953) @ org.apache.catalina.core.standardenginevalve.invoke(standardenginevalve.java:118) @ org.apache.catalina.connector.coyoteadapter.service(coyoteadapter.java:408) @ org.apache.coyote.http11.abstracthttp11processor.process(abstracthttp11processor.java:1041) @ org.apache.coyote.abstractprotocol$abstractconnectionhandler.process(abstractprotocol.java:603) @ org.apache.tomcat.util.net.jioendpoint$socketprocessor.run(jioendpoint.java:312) @ java.util.concurrent.threadpoolexecutor.runworker(unknown source) @ java.util.concurrent.threadpoolexecutor$worker.run(unknown source) @ java.lang.thread.run(unknown source) caused by: java.lang.nullpointerexception @ com.agrichem.server.services.security.customuserdetailsservice.loaduserbyusername(customuserdetailsservice.java:35) @ org.springframework.security.authentication.dao.daoauthenticationprovider.retrieveuser(daoauthenticationprovider.java:102) ... 36 more
solution:
found it! problem in websecurityconfig doing following:
@autowired public void configureglobal(authenticationmanagerbuilder auth) throws exception { auth.userdetailsservice(**new customuserdetailsservice()**); }
and new instance of custemuserdetailsservice out of spring control.
to solve added in customuserdetailsservice constructor:
private securitydao securitydao; public customuserdetailsservice(securitydao securitydao) { super(); this.securitydao = securitydao; }
and modified websecurityconfig in way:
@autowired private securitydao securitydao; @autowired public void configureglobal(authenticationmanagerbuilder auth) throws exception { auth.userdetailsservice(new customuserdetailsservice(securitydao)); }
thanks anyway help!
eventhough have solved issue, solution ugly in terms of spring dependency injection , inversion of control theories.
basically should never use new
keyword instantiate objects if using spring. because objects must instantiated , injected spring container.
applicationcontext.xml
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <context:annotation-config /> <context:spring-configured /> <context:component-scan base-package="com.agrichem.server" /> <bean id="messagesource" class="org.springframework.context.support.reloadableresourcebundlemessagesource"> <property name="basename" value="classpath:messages" /> <property name="defaultencoding" value="utf-8" /> </bean> <bean id="propertyconfigurer" class="org.springframework.beans.factory.config.propertyplaceholderconfigurer" p:location="web-inf/jdbc.properties" /> <bean id="datasource" class="org.apache.commons.dbcp.basicdatasource" destroy-method="close" p:driverclassname="${jdbc.driverclassname}" p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" /> <bean id="sessionfactory" class="org.springframework.orm.hibernate4.localsessionfactorybean"> <property name="datasource" ref="datasource" /> <property name="configlocation"> <value>classpath:hibernate.cfg.xml</value> </property> <property name="hibernateproperties"> <props> <prop key="hibernate.dialect">${jdbc.dialect}</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <tx:annotation-driven /> <bean id="transactionmanager" class="org.springframework.orm.hibernate4.hibernatetransactionmanager"> <property name="sessionfactory" ref="sessionfactory" /> </bean> <bean id="securitydao" class="com.agrichem.server.model.repositories.impl.securitydaoimpl"> </bean> <bean id="customerservice" class="com.agrichem.server.path.to.service.customuserdetailsservice"> </bean> </beans>
websecurityconfig.java
@configuration @enablewebmvcsecurity public class websecurityconfig extends websecurityconfigureradapter { @autowired private userdetailsservice customuserdetailsservice @autowired public void configureglobal(authenticationmanagerbuilder auth) throws exception { auth.userdetailsservice(customuserdetailsservice); } @override protected void configure(httpsecurity http) throws exception { http.csrf().disable(); http.authorizerequests().antmatchers("/home/logout.do").permitall() .anyrequest().authenticated().and().formlogin() .loginpage("/home/login.do").permitall() .failureurl("/home/accessdenied.do").permitall(); } }
and should have default constructor customuserdetailsservice
doesn't take in arguments. @autowired
properties should inject spring container.
furthermore intermixing spring java configuration , spring xml configuration fine, better if decide on 1 particular method define beans.
Comments
Post a Comment