Hi guys,
I get a walk around solution to postpone the injection of dao instance till the spring context is loaded.
I create a new utility class which implements the interface of ApplicationContextAware and its source code looks like following.
Code:
public class SpringContextUtil implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
MyUserDetailsService service = (MyUserDetailsService) context.getBean("myUserDetailsService");
UserDAO userDao = (UserDAO) context.getBean("userDao");
service.setUserDao(userDao);
}
}
And change my security.xml as following.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<debug />
<global-method-security pre-post-annotations="disabled" />
<http pattern="/login.xhtml*" security="none" />
<http use-expressions="true">
<intercept-url pattern="/view/**" access="ROLE_ADMINISTRATOR" requires-channel="https" />
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="https" />
<form-login login-page="/login.xhtml" default-target-url="/index.xhtml" />
<logout logout-success-url="/login.xhtml" delete-cookies="JSESSIONID"/>
</http>
<beans:bean id="myUserDetailsService" class="com.aaa.bbb.sss.auth.MyUserDetailsService">
<!-- beans:property name="userDao" ref="userDao" / -->
</beans:bean>
<authentication-manager >
<authentication-provider user-service-ref="myUserDetailsService" />
</authentication-manager>
<beans:bean id="mySpringContextUtil" class="com.aaa.bbb.sss.util.SpringContextUtil" />
</beans:beans>
However, I got another very strange issue although JPA operation is successfully done by my customized UserDetailsService. I am not sure which forum I should post this issue, here or Spring Framework or EclipseLink. The issue is about ClassCastException and output is as below.
Code:
Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.aaa.bbb.sss.model.User
at $Proxy9.findUserByNamePasswd(Unknown Source)
at com.aaa.bbb.sss.controller.UserManagementService.loginUser(UserManagementService.java:33)
at com.aaa.bbb.sss.controller.UserManagementService$$FastClassByCGLIB$$9ec5a646.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at com.aaa.bbb.sss.controller.UserManagementService$$EnhancerByCGLIB$$7da05bdc.loginUser(<generated>)
at com.aaa.bbb.sss.jsf.login.UserLogin.loginUser(UserLogin.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.el.parser.AstValue.invoke(AstValue.java:238)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 34 more
My DAO implementation of method findUserByNamePasswd is as below.
Code:
@Override
public User findUserByNamePasswd(String username, String passwd) {
if (null == username || null == passwd || "".equalsIgnoreCase(username) || "".equals(passwd)) {
return null;
}
User user = new User();
user.setUsername(username);
user.setPassword(passwd);
ReadObjectQuery roq = new ReadObjectQuery(User.class);
roq.setExampleObject(user);
System.out.println("Entity Manager is null [" + (em==null) + "]");
Query query = JpaHelper.createQuery(roq, em);
// Wrap the native query in a standard JPA Query and execute it
return (User) query.getSingleResult();
}
Any idea?
Many thanks.
Flik