Spring: cannot inject a mock into class annotated with the #Aspect annotation - spring

I created a Before advice using AspectJ:
package test.accesscontrol.permissionchecker;
import test.accesscontrol.database.SessionExpiredException;
import test.database.UsersDatabaseAccessProvider;
import test.common.constants.GlobalConstants;
import test.common.model.AbstractRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
#Aspect
public class ValidSessionChecker {
private static final int REQUEST_PARAMETER_ARGUMENT_POSITION = GlobalConstants.ZERO;
private UsersDatabaseAccessProvider usersDatabaseAccessProvider;
#Autowired
public ValidSessionChecker(UsersDatabaseAccessProvider usersDatabaseAccessProvider) {
this.usersDatabaseAccessProvider = usersDatabaseAccessProvider;
}
#Before("#annotation(test.accesscontrol.permissionchecker.ValidSessionRequired)")
public void before(JoinPoint joinPoint) throws Throwable {
Object requestParameterObject = joinPoint.getArgs()[REQUEST_PARAMETER_ARGUMENT_POSITION];
AbstractRequest requestParameter = (AbstractRequest) requestParameterObject;
String sessionID = requestParameter.getSessionId();
if(!usersDatabaseAccessProvider.sessionNotExpired(sessionID))
throw new SessionExpiredException(String.format("Session expired: %s", sessionID));
}
}
and a test class:
package test.accesscontrol;
import test.accesscontrol.database.UsersDatabaseAccessProvider;
import test.accesscontrol.permissionchecker.ValidSessionChecker;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml")
public class AccessControlControllerTestsWithInjectedMocks {
#Autowired
private org.springframework.web.context.WebApplicationContext wac;
private MockMvc mockMvc;
#Mock
UsersDatabaseAccessProvider usersDatabaseAccessProvider;
#InjectMocks
ValidSessionChecker validSessionChecker;
#InjectMocks
AccessControlController accessControlController;
#Before
public void before() throws Throwable {
//given
MockitoAnnotations.initMocks(this);
when(usersDatabaseAccessProvider.sessionNotExpired("123456")).thenReturn(Boolean.FALSE);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#Test
public void changePassword_shouldReturnUnauthorizedHttpCodeWhenSessionIsExpired() throws Exception {
//when
ResultActions results = mockMvc.perform(
post("/accesscontrol/changePassword")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"sessionId\":\"123456\", \"oldPassword\":\"password\", \"newPassword\":\"newPassword\"}")
);
//then
results.andExpect(status().isUnauthorized());
verify(usersDatabaseAccessProvider, never()).getSessionOwner(anyString());
verify(usersDatabaseAccessProvider, never()).isCurrentPasswordValid(anyString(), anyString());
verify(usersDatabaseAccessProvider, never()).setNewPassword(anyString(), anyString());
}
}
spring configuration file:
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<mvc:annotation-driven />
<aop:aspectj-autoproxy />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.context.support.ResourceBundleMessageSource"
id="messageSource">
<property name="basename" value="messages" />
</bean>
<bean id="usersDatabaseAccessProvider" class="test.accesscontrol.database.UsersDatabaseAccessProvider"/>
<bean id="accessControlController" class="test.accesscontrol.AccessControlController">
<property name="sessionExpirationTimeInSeconds" value="600"/>
</bean>
<bean id="validSessionChecker" class="test.accesscontrol.permissionchecker.ValidSessionChecker" />
<bean id="timeDispatcher" class="test.utils.time.TimeDispatcher" scope="singleton" />
</beans>
AccessControlController
#Controller
#RequestMapping("/accesscontrol")
public class AccessControlController {
...
#RequestMapping(value = "changePassword", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE)
#ValidSessionRequired
public ResponseEntity<Void> changePassword(#Valid #RequestBody ChangePasswordRequest request) throws OperationForbiddenException {
String sessionId = request.getSessionId();
String userEmailAddress = usersDatabaseAccessProvider.getSessionOwner(sessionId);
String currentPassword = request.getOldPassword();
this.ensureThatCurrentPasswordIsValid(userEmailAddress, currentPassword);
usersDatabaseAccessProvider.setNewPassword(userEmailAddress, request.getNewPassword());
return new ResponseEntity<Void>(HttpStatus.OK);
}
#ExceptionHandler({SessionExpiredException.class})
public ResponseEntity<Void> handleSessionExpiredException(Exception ex) {
return new ResponseEntity<Void>(HttpStatus.UNAUTHORIZED);
}
}
When I call mockMvc.perform(...) it should intercept method, throw an exception and return 401 Unauthorized code.
Of course it doesn't work, I tried to debug the test and:
After MockitoAnnotations.initMocks(this);
there is one instance (mock) of UsersDatabaseAccessProvider assigned to fields in all classes (ValidSessionChecker, AccessControlController and AccessControlControllerTestsWithInjectedMocks).
But when before(JoinPoint joinPoint) is executed usersDatabaseAccessProvider field in the ValidSessionChecker object contains different instance of UsersDatabaseAccessProvider (also the ValidSessionChecker object is different and it's not the mocked version).
How can I inject mocked instance of UsersDatabaseAccessProvider into ValidSessionChecker?

The issue here is that your Mock instances and the ValidSessionChecker are not Spring beans and so are not being wired into the ValidSessionChecker managed by Spring. To make the mocks Spring beans instead probably a better approach will be to create another bean definition file which extends the beans defined in the base configuration file and adds mocks:
test-config.xml:
<beans...>
<import resource="base-springmvc-config.xml"/>
<beans:bean name="usersDatabaseAccessProvider" factory-method="mock" class="org.mockito.Mockito">
<beans:constructor-arg value="..UsersDatabaseAccessProvider"></beans:constructor-arg>
</beans:bean>
And then in your test inject behavior into the mock:
public class AccessControlControllerTestsWithInjectedMocks {
#Autowired
private org.springframework.web.context.WebApplicationContext wac;
private MockMvc mockMvc;
#Autowired
UsersDatabaseAccessProvider usersDatabaseAccessProvider;
#Autowired
ValidSessionChecker validSessionChecker;
....
#Before
public void before() throws Throwable {
//given
MockitoAnnotations.initMocks(this);
when(usersDatabaseAccessProvider.sessionNotExpired("123456")).thenReturn(Boolean.FALSE);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
This should cleanly work.

Related

NullPointerException while using #Autowired in maven webapp

I am trying to integrate Jersey with Spring using maven webapp-archetype. When I get the object form the ApplicationContext I see my code executing, but when I try to use #Autowired it throws me NullPointerException. Following are the code snippets:
applicationContext.xml
<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-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.pack.resource" />
<bean id="person" class="com.pack.resource.Person">
<property name="name" value="SomeNamexxxx" />
</bean>
Person.java
package com.pack.resource;
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person() {
}
}
Hello.java
package com.pack.resource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.springframework.beans.factory.annotation.Autowired;
import javax.ws.rs.core.MediaType;
import org.springframework.stereotype.Component;
#Component
#Path("/hello")
public class Hello {
#Autowired
Person person;
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getName() {
return person.getName();
}
}
But when I use ApplicationContext.getBean("person").getName() it gives me the actual value inside the bean property.
Why is #Autowired annotation not working as it should. Kindly help me.
TIA!

Spring service injection with #Autowired results NullPointerException

I am trying to inject a service in GeofenceMonitoring class using
#Autowired
private IDeviceService deviceService;
but I am getting a NullPointerException
This is the interface of the service and below it's implementation :
IDeviceService
package com.sifast.gpstracking.service;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import com.sifast.gpstracking.model.Device;
import com.sifast.gpstracking.service.util.IGenericService;
#Transactional
public interface IDeviceService extends IGenericService<Device, Integer> {
Device findDeviceByUniqueId(String uniqueId);
List<Device> findAllDevice();
}
DeviceService
package com.sifast.gpstracking.service.impl;
import java.io.Serializable;
import java.util.List;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sifast.gpstracking.dao.impl.DeviceDao;
import com.sifast.gpstracking.model.Device;
import com.sifast.gpstracking.service.IDeviceService;
import com.sifast.gpstracking.service.util.GenericService;
#Service("deviceService")
public class DeviceService extends GenericService<Device, Integer> implements IDeviceService, Serializable {
private static final long serialVersionUID = 1L;
#Autowired
private DeviceDao deviceDao;
#Override
public Device findDeviceByUniqueId(String uniqueId) {
Query query = deviceDao.getSession().getNamedQuery("findDeviceByUniqueId").setString("uniqueId", uniqueId);
return deviceDao.findOne(query);
}
#Override
public List<Device> findAllDevice() {
return deviceDao.findAll(Device.class);
}
}
And here when I try to inject the service :
GeofenceMonitoring
package com.sifast.gpstracking.webServiceRest;
import java.util.ArrayList;
import java.util.List;
import org.primefaces.model.map.LatLng;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import com.sifast.gpastracking.monitoring.IMonitor;
import com.sifast.gpstracking.model.Device;
import com.sifast.gpstracking.model.Geofence;
import com.sifast.gpstracking.model.GeofenceDevice;
import com.sifast.gpstracking.model.Point;
import com.sifast.gpstracking.push.DevicePositionData;
import com.sifast.gpstracking.service.IDeviceService;
import com.sifast.gpstracking.service.util.IntersectionGeofence;
#ComponentScan("com.sifast.gpstracking")
public class GeofenceMonitor implements IMonitor {
ArrayList<Geofence> geofences = new ArrayList<Geofence>();
GeofenceDevice geofenceDevice;
Boolean geofenced=false;
public static final Logger logger = LoggerFactory.getLogger(GeofenceMonitor.class);
#Autowired
private IDeviceService serviceDevice;
public GeofenceMonitor() {
}
#Override
public void updateMonitor(DevicePositionData devicePositionData) {
//logger.debug("DEVICE ID = " + devicePositionData.getUniqueId());
Device device = serviceDevice.findDeviceByUniqueId(devicePositionData.getUniqueId());
LatLng currentPosition = new LatLng(devicePositionData.getLatitude(), devicePositionData.getLongitude());
for (GeofenceDevice geofenceDevice : device.getListGeofenceDevice()) {
List<LatLng> listPoint = convertListPointToListLatLng(geofenceDevice.getGeofence().getListPoint());
logger.debug("SIZE =====> "+listPoint.size());
if (IntersectionGeofence.isPointInsidePolygon(currentPosition, listPoint))
{
geofenced = true;
logger.debug("Le device " + devicePositionData.getDeviceName() + " a dépassé la zone limitée");
break;
}
}
}
private List<LatLng> convertListPointToListLatLng(List<Point> listPoint)
{
List<LatLng> listLatLng = new ArrayList<LatLng>();
for (Point point : listPoint){
listLatLng.add(new LatLng(point.getLatitude(),point.getLongitude()));
}
return listLatLng;
}
}
And finally 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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
<!-- Activates scanning of annotations -->
<context:component-scan base-package="com.sifast.gpstracking" />
<context:annotation-config/>
<context:spring-configured/>
<!-- Database Configuration -->
<import resource="/database/dataSource.xml" />
<import resource="/database/hibernate.xml" />
<!-- Transaction Manager is defined -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager" />
<mvc:annotation-driven></mvc:annotation-driven>
<!-- Pour avoir accès au resources comme les fichiers /js et /css lorsqu'on utilise un mapping / avec le servletDispatcher dans le web.xml -->
<mvc:resources mapping="/css/**" location="/resources/css/" />
<mvc:resources mapping="/images/**" location="/resources/images/" />
<!-- Init DataBase -->
<bean id="dbInit"
class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
<property name="scripts">
<list>
<value>classpath:sql/1.0.0/CreateData.sql</value>
</list>
</property>
<property name="continueOnError" value="true" />
</bean>
<bean id="startupScripts"
class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="databasePopulator">
<ref bean="dbInit" />
</property>
</bean>
</beans>
It's because that IDeviceService is an interface. Spring won't know which instance you want to autowire, since the default way to autowire is byType, if I'm not wrong.
Try this
#Autowired
#Qualifier("deviceService")
private IDeviceService deviceService;
try double stars first
<context:component-scan base-package="com.sifast.gpstracking.**" />
An simple example to get bean via applicationContext.getBean()
http://www.mkyong.com/spring/quick-start-maven-spring-example/
And you want to get it in web environment, you can inject it.
How to inject ApplicationContext itself
Is your GeofenceMonitor bean registered in the application context ? From your code snippets its missing streotype annotations (#Component / #Service etc) So it wont be auto detected and any specified dependencies wont be injected. Change #ComponentScan("com.sifast.gpstracking")
public class GeofenceMonitor implements IMonitor to #Component public class GeofenceMonitor implements IMonitor
the problem was that I am creating a new instance of GeofenceMonitor with new GeofenceMonitor() in a service class that's meant to handle the web service invokation.
So I modified it to #Scope("singleton") and added #PostConstruct private void init(). Below is my code:
PositionNotification (web service class)
#Service("positionNotification")
#Path("/positionNotification")
#Scope("singleton")
public class PositionNotification implements Serializable, IMonitorable {
private static final long serialVersionUID = 1L;
#Autowired
private GeofenceMonitor geofence;
private static ArrayList<IMonitor> monitors;
/*static {
monitors = new ArrayList<IMonitor>();
monitors.add(new SpeedMonitor());
monitors.add(geofence);
}*/
#Autowired
private IDeviceService deviceService;
#Autowired
private IPositionService positionService;
private final static String CHANNEL = "/notify";
public static final Logger logger = LoggerFactory.getLogger(PositionNotification.class);
private static final int STATUS_OK = 200;
#PostConstruct
private void init(){
monitors = new ArrayList<IMonitor>();
monitors.add(new SpeedMonitor());
monitors.add(geofence);
}
#POST
#Path("/getGeoLocFromDevice")
public Response test(#FormParam("LATITUDE") String latitude, #FormParam("LONGITUDE") String longitude, #FormParam("DEVICE_ID") String uniqueId,
#FormParam("SPEED") String speed, #FormParam("Horodateur") String date) {
logger.debug("X long: " + latitude + " __ Y lat: " + longitude + " uniqueId " + uniqueId + " " + date);
Device device = deviceService.findDeviceByUniqueId(uniqueId);
if (device != null) {
if (speed == null) {
speed = "0";
}
String address = AddressResolver.AddressReseolve(latitude, longitude);
DevicePositionData devicePositionData = new DevicePositionData();
devicePositionData.setLatitude(Double.valueOf(latitude));
devicePositionData.setLongitude(Double.valueOf(longitude));
devicePositionData.setUniqueId(uniqueId);
devicePositionData.setAddress(address);
devicePositionData.setDeviceName(device.getName());
devicePositionData.setSpeed(Double.parseDouble(speed));
devicePositionData.setIcon(device.getType().getIconActive());
Position position = new Position();
position.setAddress(address);
position.setLatitude(Double.valueOf(latitude));
position.setLongitude(Double.valueOf(longitude));
if (date != null) {
try {
position.setDatePosition(new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse(date));
devicePositionData.setDatePosition(date);
device.setLastUpdate(new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse(date));
} catch (ParseException e) {
e.printStackTrace();
}
} else {
position.setDatePosition(new Date());
devicePositionData.setDatePosition(new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date()));
device.setLastUpdate(new Date());
}
position.setSpeed(Double.parseDouble(speed));
position.setDevice(device);
positionService.saveOrUpdateService(position);
deviceService.saveOrUpdateService(device);
if (EventBusFactory.getDefault() != null) {
EventBus eventBus = EventBusFactory.getDefault().eventBus();
eventBus.publish(CHANNEL, devicePositionData);
}
notifyMonitors(devicePositionData);
}
return Response.status(STATUS_OK).build();
}
#Override
public void notifyMonitors(DevicePositionData devicePositionData) {
for (IMonitor monitor : monitors) {
monitor.updateMonitor(devicePositionData);
}
}
#Override
public void addMonitor(IMonitor monitor) {
monitors.add(monitor);
}
#Override
public void deleteMonitor(IMonitor monitor) {
monitors.remove(monitor);
}
#Override
public void clearMonitors() {
monitors.clear();
}
}

Handling Exception In Spring Standalone Application

i have created Standalone application in spring.
for exception handling i am using custom exception handler which extends SimpleMappingExceptionResolver class.
whenever exception occurs in program i want to delegate it to specific java method.
how do i do that ?
i saw lots of examples on the net, but everywhere exception handling done on .jsp page.
how i catch the exception in java method.
here is my bean config file
<bean class="com.ys.core.exception.ExceptionHandler">
<property name="exceptionMappings">
<props>
<prop key="com.ys.core.exception.MyException">ExceptionHandler</prop>
<prop key="java.lang.Exception">ExceptionHandler</prop>
<prop key="java.lang.ArithmeticException">ExceptionHandler</prop>
</props>
</property>
</bean>
<bean id="exceptionHandler" class="com.ys.core.exception.ExceptionHandler" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/com/ys/core/service/myservices" />
<property name="suffix" value=".java" />
</bean>
can i do like this ?
means call .java class instead of jsp file ?
ExceptionProcessorAspect : It's an after throwing aspect which is handling a Pointcut with annotation : ExceptionAnnotation
In side the #AfterThrowing handler, exception Processor is triggered which is based on the Command Pattern
#AfterThrowing(pointcut = "getExceptionPointcut()", throwing ="error")
public void processor(JoinPoint call,Throwable error){
if(null!=call){
MethodSignature signature = (MethodSignature) call.getSignature();
Method method = signature.getMethod();
ExceptionAnnotation myAnnotation = method.getAnnotation(ExceptionAnnotation.class);
Class<?> value = myAnnotation.value();
AbstractExceptionProcessor exceptionProcessor = (AbstractExceptionProcessor)this.exceptionMap.get(value);
exceptionProcessor.processException(error);
}
}
Other classes are the supporting components that make up an #AfterThrwoing aspect
1.ExceptionAnnotation : a base on which the pointcut is made
2.SystemException : which will be thrown from a TestExceptionClass.testEx1
package com.spring;
public abstract class AbstractExceptionProcessor {
public void processException(Throwable error){
System.out.println("Processed "+error);
}
}
..............................................................................
package com.spring;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
#Component("com.spring.ExceptionProcessorAspect")
#Aspect
public class ExceptionProcessorAspect {
//#Value("#{exceptionMap}")
private Map<Class<?>,AbstractExceptionProcessor> exceptionMap;
#Autowired
#Qualifier("com.spring.SystemExceptionProcessor")
private SystemExceptionProcessor systemExceptionProcessor;
#Autowired
#Qualifier("com.spring.UnsupportedExceptionProcessor")
private UnsupportedExceptionProcessor unsupportedExceptionProcessor;
public ExceptionProcessorAspect(){
}
#PostConstruct
public void init(){
this.exceptionMap = new HashMap<Class<?>,AbstractExceptionProcessor>();
exceptionMap.put(SystemException.class, systemExceptionProcessor);
exceptionMap.put(UnsupportedException.class, unsupportedExceptionProcessor);
}
#Pointcut("#annotation(ExceptionAnnotation)")
public void getExceptionPointcut(){
}
#AfterThrowing(pointcut = "getExceptionPointcut()", throwing ="error")
public void processor(JoinPoint call,Throwable error){
if(null!=call){
MethodSignature signature = (MethodSignature) call.getSignature();
Method method = signature.getMethod();
ExceptionAnnotation myAnnotation = method.getAnnotation(ExceptionAnnotation.class);
Class<?> value = myAnnotation.value();
AbstractExceptionProcessor exceptionProcessor = (AbstractExceptionProcessor)this.exceptionMap.get(value);
exceptionProcessor.processException(error);
}
}
}
................................................................................................................................................................
package com.spring;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface ExceptionAnnotation {
Class<?> value();
}
................................................................................................................................................................
/**
*
*/
package com.spring;
public class SystemException extends RuntimeException {
public SystemException(String message) {
super(message);
this.message = message;
}
String message;
}
................................................................................................................................................................
package com.spring;
import org.springframework.stereotype.Component;
#Component("com.spring.SystemExceptionProcessor")
public class SystemExceptionProcessor extends AbstractExceptionProcessor {
#Override
public void processException(Throwable error) {
// TODO Auto-generated method stub
System.out.println("Processed " + error.getMessage());
}
}
................................................................................................................................................................
package com.spring;
import org.springframework.stereotype.Component;
#Component
public class TestExceptionClass {
#ExceptionAnnotation(value=SystemException.class)
public void testEx1(){
System.out.println("In SystemException Block" );
if(1==Integer.parseInt("1")){
throw new SystemException("SystemException raised");
}
System.out.println("After throws Block SystemException");
}
}
................................................................................................................................................................
/**
*
*/
package com.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BootClass {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-resources/config.xml");
System.out.println("Spring context initialized.");
TestExceptionClass test = applicationContext.getBean(TestExceptionClass.class);
test.testEx1();
}
}

java.lang.NullPointerException on #Inject Dao

I'm trying to Inject a DAO into #Service component, but I get this error :
Exception in thread "main" java.lang.NullPointerException at
it.cle.project.service.impl.TestEntityServiceImpl.getListTestEntity(TestEntityServiceImpl.java:24).
Fails to call the DAO which is null despite the annotation #Autowired
Below my code:
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
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/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-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/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- INIZIO IMPOSTAZIONI LEGATE ALLE ANNOTATIONS -->
<tx:annotation-driven/>
<context:property-placeholder location="classpath:hibernate.properties"/>
<context:component-scan base-package="it.cle.project.service.impl" />
<context:component-scan base-package="it.cle.project.dao.hbn" />
<context:component-scan base-package="it.cle.project.dao.hibernate" />
<!-- FINE IMPOSTAZIONI LEGATE ALLE ANNOTATIONS -->
<!-- INIZIO IMPOSTAZIONI LEGATE AD ALTRI FILE DI CONFIGURAZIONE -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:hibernate.properties"/>
</bean>
<!-- FINE IMPOSTAZIONI LEGATE AD ALTRI FILE DI CONFIGURAZIONE -->
<!-- INIZIO IMPOSTAZIONI LEGATE ALLA CONNESSIONE -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory" />
<util:properties id="hibernateProperties">
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl_auto}</prop>
</util:properties>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean "
p:dataSource-ref="dataSource" p:packagesToScan="it.cle.project.model"
p:hibernateProperties-ref="hibernateProperties" />
<!-- FINE IMPOSTAZIONI LEGATE ALLA CONNESSIONE -->
App.java
package it.cle.project;
import it.cle.project.model.TestEntity;
import it.cle.project.service.impl.TestEntityServiceImpl;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App
{
public static void main( String[] args )
{
ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
System.out.println( "Hello World!" );
TestEntity testEntity = new TestEntity();
testEntity.setCampoUno("Campo Uno");
testEntity.setCampoDue("Campo Due");
testEntity.setEmail("email#test.it");
TestEntityServiceImpl testEntityServiceImpl = new TestEntityServiceImpl();
List<TestEntity> testEntitys = testEntityServiceImpl.getListTestEntity();
}
}
DAO Interface
package it.cle.project.dao;
import java.io.Serializable;
import java.util.List;
public interface Dao<T extends Object> {
void create(T t);
T get(Serializable id);
T load(Serializable id);
List<T> getAll();
void update(T t);
void delete(T t);
void deleteById(Serializable id);
void deleteAll();
long count();
boolean exists(Serializable id);
}
TestEntityDAO interface
package it.cle.project.dao;
import it.cle.project.model.TestEntity;
import java.util.List;
public interface TestEntityDao extends Dao<TestEntity> {
List<TestEntity> findByEmail(String email);
}
AbstractHbnDao Abstract class:
package it.cle.project.dao.hibernate;
import it.cle.project.dao.Dao;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;
#Service
public abstract class AbstractHbnDao<T extends Object> implements Dao<T> {
#Autowired
private SessionFactory sessionFactory;
private Class<T> domainClass;
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
private Class<T> getDomainClass() {
if (domainClass == null) {
ParameterizedType thisType =
(ParameterizedType) getClass().getGenericSuperclass();
this.domainClass =
(Class<T>) thisType.getActualTypeArguments()[0];
}
return domainClass;
}
private String getDomainClassName() {
return getDomainClass().getName();
}
public void create(T t) {
Method method = ReflectionUtils.findMethod(
getDomainClass(), "setDataCreazione",
new Class[] { Date.class });
if (method != null) {
try {
method.invoke(t, new Date());
} catch (Exception e) { /* Ignore */ }
}
getSession().save(t);
}
#SuppressWarnings("unchecked")
public T get(Serializable id) {
return (T) getSession().get(getDomainClass(), id);
}
#SuppressWarnings("unchecked")
public T load(Serializable id) {
return (T) getSession().load(getDomainClass(), id);
}
#SuppressWarnings("unchecked")
public List<T> getAll() {
return getSession()
.createQuery("from " + getDomainClassName())
.list();
}
public void update(T t) { getSession().update(t); }
public void delete(T t) { getSession().delete(t); }
public void deleteById(Serializable id) { delete(load(id)); }
public void deleteAll() {
getSession()
.createQuery("delete " + getDomainClassName())
.executeUpdate();
}
public long count() {
return (Long) getSession()
.createQuery("select count(*) from " + getDomainClassName())
.uniqueResult();
}
public boolean exists(Serializable id) { return (get(id) != null); }
}
HbnTestEntityDao class DAO
package it.cle.project.dao.hbn;
import it.cle.project.dao.TestEntityDao;
import it.cle.project.dao.hibernate.AbstractHbnDao;
import it.cle.project.model.TestEntity;
import java.util.List;
import org.springframework.stereotype.Repository;
#Repository
public class HbnTestEntityDao extends AbstractHbnDao<TestEntity> implements TestEntityDao {
#SuppressWarnings("unchecked")
public List<TestEntity> findByEmail(String email) {
return getSession()
.getNamedQuery("findContactsByEmail")
.setString("email", "%" + email + "%")
.list();
}
}
TestEntityService interface service
package it.cle.project.service;
import it.cle.project.model.TestEntity;
import java.util.List;
public interface TestEntityService {
void createTestEntity(TestEntity testEntity);
List<TestEntity> getListTestEntity();
List<TestEntity> getTestEntityByEmail(String email);
TestEntity getTestEntity(Integer id);
void updateTestEntity(TestEntity testEntity);
void deleteTestEntity(Integer id);
}
TestEntityServiceImpl
package it.cle.project.service.impl;
import it.cle.project.dao.TestEntityDao;
import it.cle.project.model.TestEntity;
import it.cle.project.service.TestEntityService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
#Transactional
public class TestEntityServiceImpl implements TestEntityService {
#Autowired
private TestEntityDao testEntityDao;
public void createTestEntity(TestEntity testEntity) {
testEntityDao.create(testEntity);
}
public List<TestEntity> getListTestEntity() {
return testEntityDao.getAll();
}
public List<TestEntity> getTestEntityByEmail(String email) {
return testEntityDao.findByEmail(email);
}
public TestEntity getTestEntity(Integer id) {
return testEntityDao.get(id);
}
public void updateTestEntity(TestEntity testEntity) {
testEntityDao.update(testEntity);
}
public void deleteTestEntity(Integer id) {
testEntityDao.deleteById(id);
}
}
Any ideas?
Thanks.
Your TestServiceImpl should be spring managed bean and should be fetched from Spring application context (by injection or by explicit asking the context). As the component scanning is at work, your TestServiceImpl is already managed with Spring's own supplied name (com...TestServiceImpl becomes testServiceImpl). You can give it your name like
#Service("myTestServiceImpl")
The instead of creating the bean yourself you can query this named bean from application context and use it.
That's some wall of text. I stopped at:
TestEntityServiceImpl testEntityServiceImpl = new TestEntityServiceImpl();
You created an unmanaged bean. Spring has no control over that. Put TestEntityServiceImpl into your spring context.

#Autowired field get null

I have this property-editor for my class Categoria and im trying to auto-wired it to the service, the problem its that the services keep getting a null value.
Also it seems like this is isolated or at least thats what i think, because i auto-wired a field of the same class at a controller, so i don't know whats going on, i already got an error like this, but at that time it didn't work at all .
Convertor
package com.carloscortina.paidosSimple.converter;
import java.beans.PropertyEditorSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.carloscortina.paidosSimple.model.Categoria;
import com.carloscortina.paidosSimple.service.CategoriaService;
public class CategoriaConverter extends PropertyEditorSupport{
private final Logger logger = LoggerFactory.getLogger(CategoriaConverter.class);
#Autowired
private CategoriaService categoriaService;
#Override
public void setAsText(String categoria) {
logger.info(categoria);
Categoria cat = new Categoria();
cat = categoriaService.getCategoria(Integer.parseInt(categoria));
setValue(cat);
}
}
Service
package com.carloscortina.paidosSimple.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.carloscortina.paidosSimple.dao.CategoriaDao;
import com.carloscortina.paidosSimple.model.Categoria;
#Service
#Transactional
public class CategoriaServiceImpl implements CategoriaService{
#Autowired
private CategoriaDao categoriaDao;
#Override
public Categoria getCategoria(int id) {
// TODO Auto-generated method stub
return categoriaDao.getCategoria(id);
}
#Override
public List<Categoria> getCategorias() {
return categoriaDao.getCategorias();
}
}
Here It does Work
Controller
package com.carloscortina.paidosSimple.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.carloscortina.paidosSimple.converter.CategoriaConverter;
import com.carloscortina.paidosSimple.model.Categoria;
import com.carloscortina.paidosSimple.model.Personal;
import com.carloscortina.paidosSimple.model.Usuario;
import com.carloscortina.paidosSimple.service.CategoriaService;
import com.carloscortina.paidosSimple.service.PersonalService;
import com.carloscortina.paidosSimple.service.UsuarioService;
#Controller
public class PersonalController {
private static final Logger logger = LoggerFactory.getLogger(PersonalController.class);
#Autowired
private PersonalService personalService;
#Autowired
private UsuarioService usuarioService;
#Autowired
private CategoriaService categoriaService;
#RequestMapping(value="/usuario/add")
public ModelAndView addUsuarioPage(){
ModelAndView modelAndView = new ModelAndView("add-usuario-form");
modelAndView.addObject("categorias",categorias());
modelAndView.addObject("user", new Usuario());
return modelAndView;
}
#RequestMapping(value="/usuario/add/process",method=RequestMethod.POST)
public ModelAndView addingUsuario(#ModelAttribute Usuario user){
ModelAndView modelAndView = new ModelAndView("add-personal-form");
usuarioService.addUsuario(user);
logger.info(modelAndView.toString());
String message= "Usuario Agregado Correctamente.";
modelAndView.addObject("message",message);
modelAndView.addObject("staff",new Personal());
return modelAndView;
}
#RequestMapping(value="/personal/list")
public ModelAndView listOfPersonal(){
ModelAndView modelAndView = new ModelAndView("list-of-personal");
List<Personal> staffMembers = personalService.getAllPersonal();
logger.info(staffMembers.get(0).getpNombre());
modelAndView.addObject("staffMembers",staffMembers);
return modelAndView;
}
#RequestMapping(value="/personal/edit/{id}",method=RequestMethod.GET)
public ModelAndView editPersonalPage(#PathVariable int id){
ModelAndView modelAndView = new ModelAndView("edit-personal-form");
Personal staff = personalService.getPersonal(id);
logger.info(staff.getpNombre());
modelAndView.addObject("staff",staff);
return modelAndView;
}
#RequestMapping(value="/personal/edit/{id}", method=RequestMethod.POST)
public ModelAndView edditingPersonal(#ModelAttribute Personal staff, #PathVariable int id) {
ModelAndView modelAndView = new ModelAndView("home");
personalService.updatePersonal(staff);
String message = "Personal was successfully edited.";
modelAndView.addObject("message", message);
return modelAndView;
}
#RequestMapping(value="/personal/delete/{id}", method=RequestMethod.GET)
public ModelAndView deletePersonal(#PathVariable int id) {
ModelAndView modelAndView = new ModelAndView("home");
personalService.deletePersonal(id);
String message = "Personal was successfully deleted.";
modelAndView.addObject("message", message);
return modelAndView;
}
private Map<String,String> categorias(){
List<Categoria> lista = categoriaService.getCategorias();
Map<String,String> categorias = new HashMap<String, String>();
for (Categoria categoria : lista) {
categorias.put(Integer.toString(categoria.getId()), categoria.getCategoria());
}
return categorias;
}
#InitBinder
public void initBinderAll(WebDataBinder binder){
binder.registerCustomEditor(Categoria.class, new CategoriaConverter());
}
}
DAO
package com.carloscortina.paidosSimple.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.carloscortina.paidosSimple.converter.CategoriaConverter;
import com.carloscortina.paidosSimple.model.Categoria;
#Repository
public class CategoriaDaoImp implements CategoriaDao {
private final Logger logger = LoggerFactory.getLogger(CategoriaConverter.class);
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
#Override
public Categoria getCategoria(int id) {
Categoria rol = (Categoria) getCurrentSession().get(Categoria.class, id);
if(rol == null) {
logger.debug("Null");
}else{
logger.debug("Not Null");
}
logger.info(rol.toString());
return rol;
}
#Override
#SuppressWarnings("unchecked")
public List<Categoria> getCategorias() {
// TODO Auto-generated method stub
return getCurrentSession().createQuery("from Categoria").list();
}
}
root-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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- Enable transaction Manager -->
<tx:annotation-driven/>
<!-- DataSource JNDI -->
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/paidos" resource-ref="true" />
<!-- Session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource"
p:hibernateProperties-ref="hibernateProperties"
p:packagesToScan="com.carloscortina.paidosSimple.model" />
<!-- Hibernate Properties -->
<util:properties id="hibernateProperties">
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5InnoDBDialect
</prop>
<prop key="hibernate.show_sql">false</prop>
</util:properties>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<context:annotation-config />
<context:component-scan base-package="com.carloscortina.paidosSimple,com.carlosocortina.paidosSimple.converter,com.carlosocortina.paidosSimple.service,com.carlosocortina.paidosSimple.dao" />
</beans>
Thanks in advance
Your are creating your PropertyEditor outside spring context using new operator (binder.registerCustomEditor(Categoria.class, new CategoriaConverter());) so service is not injected: follow the guide at this link to solve your problem.

Resources