#Autowired bean null into JSF ManagedBean, with Spring xml configuration - java

I use xml configuration to declare my UserDao bean, and call it into another component: AuthenticationFacade (declared by #Component annotation) using #Autowired annotation like this:
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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<context:component-scan base-package="com.medkhelifi.tutorials.todolist"/>
<import resource="classpath:/conf/applicationContext-db.xml"/>
<import resource="classpath:/conf/applicationContext-security.xml"/>
</beans>
applicationContext-db.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!--.....-->
<!-- DAO BEANS -->
<bean id="userDao" class="com.medkhelifi.tutorials.todolist.models.dao.impl.UserDaoImp">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--....->
</beans>
AuthenticationFacade.java
package com.medkhelifi.tutorials.todolist.components;
import com.medkhelifi.tutorials.todolist.models.dao.UserDao;
import com.medkhelifi.tutorials.todolist.models.entities.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import javax.faces.bean.ManagedBean;
#Component
#ManagedBean
#Scope("session")
public class AuthenticationFacade implements IAuthenticationFacade {
#Autowired
private UserDao userDao;
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
public User getAuthenticatedFacade() {
Authentication authentication = getAuthentication();
User user = userDao.findByUsername(authentication.getName());
return user;
}
}
With this configuration I get userDao as null, I don't know if I missed something.
There is where I use my AuthenticationFacade managedBean:
index.xhtml
<h:body>
<ui:composition template="templates/layout.xhtml">
<ui:define name="content">
<b:row>
<b:navBar brand="Brand" brandHref="#" fluid="true">
  <!-- Following line is needed for TBS 3.0.1 (panel content overflow issue) -->
<b:navbarLinks pull="right"><b:navLink value="    " href="#"></b:navLink></b:navbarLinks>
   <b:navbarLinks pull="right" styleClass="hidden-xs">
     <b:dropMenu value="#{authenticationFacade.getAuthenticatedFacade().firstname}">
       <b:navLink value="logout" href="#"></b:navLink>
     </b:dropMenu>
   </b:navbarLinks>
</b:navBar>
</b:row>
</ui:define>
</ui:composition>
</h:body>

After a few hours of searching, I found where I messed:
I forgot to add SpringBeanFacesELResolver to my faces-config.xml.
faces-config.xml
<application>
<!-- I forgot to add this resolver to my faces-config.xml -->
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

Related

Spring's Cacheable not working - Not returning results from Cache

I'm trying to use Spring #Cacheable on a Method but its Not Working.
import org.springframework.cache.annotation.Cacheable;
public class CacheableService {
#Cacheable(value = "entityCount")
public int someEntityCount(final String criteria) {
System.out.println("Inside function : " + criteria);
return 5;
} }
Beans Initialization :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<cache:annotation-driven />
<context:annotation-config/>
<aop:aspectj-autoproxy />
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean name = "impactLevelsCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<property name="name" value="impactLevels" />
</bean>
<bean name = "entityCountBean" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<property name="name" value="entityCount" />
</bean>
</set>
</bean>
</beans>
I am not Getting what mistake I'm making. It always invoking the method. I have also enabled Trace Logs but its not logging anything specific to Caching.
Also tried calling it from test cases, but cache not working. (Invocation is from different class. There is no Self-Invocation).
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
// Using same Bean configuration for Testing also.
#ContextConfiguration(locations = "/com/amazon/pickuppointcapacity/test/appconfig2.xml")
public class RoughTest {
#Test
public void testSomeEntityCountCalledTwice_shouldCallDaoMethodOnce() {
CacheableService cacheableService = new CacheableService();
cacheableService.someEntityCount("A");
cacheableService.someEntityCount("A");
cacheableService.someEntityCount("A");
cacheableService.someEntityCount("A");
}
}
Please help me out.
You are creating a new instance of CacheableService in your test, which means it is not managed by Spring and non of the Spring annotations will work in it.
For spring to kick in, you need to get your service as a bean, autowired into your test class

Spring - autowired fields are null

I faced a problem with Spring Framework: #Autowired are null, but Spring doesn't throw any exceptions, and I can't understand, why are these fields null.
I have a class:
package com.processing.gates;
public class Main {
private final ApplicationContext context = Context.getContext();
#Autowired private PaymentGateFactory paymentGateFactory;
#Autowired private CalculatorChooser calculatorChooser;
//...
}
And for example I have the following class:
package com.processing.gates.comission;
#Component
public class CalculatorChooser {
//...
}
Here is my Spring configuration xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<context:annotation-config />
<context:component-scan base-package="com.processing.gates"/>
<bean id="logPath" class="java.lang.String"> <!-- путь к папке с логами -->
<constructor-arg value="/home/yoba/NetBeansProjects/processing/gates/log/"/>
</bean>
<!-- ... -->
</beans>
When I try to write in xml:
<bean id="calculator" class="com.processing.gates.comission.CalculatorChooser"/>
and get it from code:
CalculatorChooser cc = (CalculatorChooser)Context.getContext().getBean("calculator");
it works fine. But #Autowired doesn't work. How can I fix this? Thanks!
Let Spring manage the bean by either declaring a Main bean in the application context file or by using the #Component annotation as you've already done for CalculatorChooser
<bean id="mainBean" class="com.processing.gates.Main"/>

Spring #Autowired comes as null

I have #Component, A, which AutoWires a class which contains simple configurations for class A. I've created a bin for configuration file. But for some reason it comes as null. Could you please help me to find out the problem?
#Component
public class SearchEngineDriver {
#Autowired(required = true)
private EngineContext context;
public SearchEngineDriver(){
String clusterName = context.getClusterName();
}
}
public class EngineContext {
private String clusterName;
public EngineContext(String clusterName){
this.clusterName = clusterName;
}
public String getClusterName(){
return this.clusterName;
}
}
3rd class.
#Autowired
private SearchEngineDriver searchEngineDriver;
mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="org.electronsoftware" />
<mvc:annotation-driven/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<import resource="classpath*:/application-context.xml"/>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
application-context.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:property-placeholder location="classpath:application.properties"/>
<bean id="searchEngineContext" class="org.electronsoftware.KGB.search.context.EngineContext" >
<constructor-arg value="${kgb.search.engine.clustername}"/>
</bean>
</beans>
You are accessing the autowired field from the constructor. At the time the constructor runs, Spring has not yet got the chance to initialize the field. Instead use a #PostConstruct method to perform logic which depends on the autowired value.

Spring #Value annotation and setter injection difference

When I am setting a value using #Value annotation from a property file, its not working, whereas setting using setter injection works.
my properties file like this.
app.work.dir=file:${user.home}/WORK
class file like below.
#Value("#{configProperties['app.work.dir']}")
private String workdir;
and this is my xml setting.
<util:properties id="configProperties" location="classpath:config.properties" />
when use setter injection like below then it works fine.
<bean id="sampleService" class="aaa.SampleService">
<property name="workdir" value="${app.work.dir}" />
</bean>
I'm not sure why and if possible i want to use #Value annotation.
please refer to junit test case below.
xml configulation:
<?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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:property-placeholder location="classpath:testconfig.properties" />
<util:properties id="sampleProperties" location="classpath:testconfig.properties" />
<bean id="exampleA" class="aa.sample.SampleA" />
<bean id="sampleB" class="aa.sample.SampleB" >
<property name="workdir" value="${work.dir}" />
<property name="tempdir" value="${work.dir.test}" />
<property name="aaa" value="${aaa}" />
</bean>
</beans>
sample service class:
package aa.sample;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
#Service
public class SampleA {
#Value("#{sampleProperties['work.dir']}")
private String workdir;
#Value("#{sampleProperties['work.dir.test']}")
private String tempdir;
#Value("#{sampleProperties['aaa']}")
private String aaa;
//getter setter deleted
}
properties file:
work.dir=file:${user.home}/WORK
work.dir.test=${work.dir}/TEST
aaa=bbb
and junit test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "/testcontext.xml" })
public class ExampleTest {
#Inject
private SampleA sampleA;
#Inject
private SampleB sampleB;
#Test
public void testValueAnnotation() {
assertThat(sampleA.getAaa(), is("bbb"));//ok
String tempdir = sampleA.getTempdir();
String workdir = sampleA.getWorkdir();
assertFalse("[sampleA] temp dir should not have ${work.dir}", tempdir.indexOf("${work.dir}") >= 0);//ng
assertFalse("[sampleA] workdir dir should not have ${user.home}", workdir.indexOf("${user.home}") >= 0);//ng
}
}
The bean generated by
<util:properties id="sampleProperties" location="classpath:spring.properties" />
basically translates to a map. This notation
#Value("#{sampleProperties['work.dir']}")
requests one of its valued mapped with the key work.dir. There's no property resolution that occurs on the value returned. It's taken literally.
This, on the other hand,
<property name="tempdir" value="${work.dir.test}" />
requests a property, called work.dir.test which can be recursively resolved.

Spring autowired dao is null

I am attempting to create rest web services to handle CRUD operations for an android application. I'm using Spring 4.0 with Hibernate. I'm trying to autowire a dao and it's always null and I haven't been able to figure out the cause of the issue. I searched online and everything looks right to me so I'm at a complete lost. I defined the bean in the applicationContext as I have saw in many tutorials but I'm unable to get the dao to autowire. Any help would be appreciated.
dispatch-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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:annotation-config />
<mvc:annotation-driven />
<context:component-scan base-package="com.bike.party.services, com.bike.party.daos" />
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="propertyConfigurer" p:location="/WEB-INF/jdbc.properties"/>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource" p:driverClassName="${jdbc.driverClassName}" p:password="${jdbc.password}" p:url="${jdbc.url}" p:username="${jdbc.username}"/>
<!-- ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) -->
<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" id="sessionFactory">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="com.bike.party.models"/>
</bean>
<bean class="org.springframework.orm.hibernate4.HibernateTransactionManager" id="transactionManager" p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven/>
</beans>
UserDao
package com.bike.party.daos;
import com.bike.party.models.User;
public interface UserDao extends Dao<User> {
public User findByUserName(String username);
}
UserDaoImpl
package com.bike.party.daos;
import com.bike.party.models.User;
import java.util.List;
import javax.transaction.Transactional;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
#Repository
#Transactional
#Qualifier("userDaoImpl")
public class UserDaoImpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public User findByUserName(String username) {
List<User> userList = sessionFactory.getCurrentSession().createCriteria(User.class).add(Restrictions.eq("username", username)).setMaxResults(1).list();
return userList.isEmpty() ? null : userList.get(0);
}
}
UserWebService
package com.bike.party.services;
import com.bike.party.daos.UserDao;
import com.bike.party.models.User;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Provider
#Component
#Path("userservice")
public class UserWebService {
#Autowired
private UserDao userDao;
#GET
#Path("/user/{username}")
#Produces(MediaType.TEXT_PLAIN)
public String getUser(String username) {
if (userDao == null) {
return "the dao is null";
}
User user = userDao.findByUserName(username);
if (user == null) {
return "No user was found.";
} else {
return user.getUsername();
}
}
}
UPDATE:
I modified the UserWebService with
private UserDao userDao;
#Autowired
public void setUserDao(UserDao userDao) {
if (functionDao != null) {
System.out.println(String.valueOf(userDao.findByUserName("chris")));
} else {
System.out.println("setting the dao is null :(");
}
this.userDao= userDao;
}
When the web app is deployed this is called and finds the user but when I call it from the client it is always null. Could this be because I'm calling the service directly and not going through spring? If so could any point me to the create way to call the service from the client. Thanks
i believe spring can not find your UserDao class.
try to change your component-scan instruction in dispatch-servlet.xml to this one:
<context:component-scan base-package="com.bike.party.*" />
If you're using Spring Tool Suite all #Component's in your project should be marked as Component(icon with S):
EDIT:
remove bean definition from xml, do not mix xml and annotated configuration.
Remove also "userDaoImpl" from your Annotations. Change #Repository("userDaoImpl") to #Repository()
Remove the <bean id="userDao" class="com.bike.party.daos.UserDaoImpl" /> bean from the applicationContext.xml file.
I think you are injecting this instance instead of the the one that gets created via the #Repository annotation which is why your SessionFactory is null
Try to derive your UserWebService from SpringBeanAutowiringSupport.

Categories