Handling Exception In Spring Standalone Application - spring

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();
}
}

Related

injecting template class interface in the spring bean xml file

i am using template interface to cast to the required DAO, but i need to place it in the bean xml file so that i can inject the datasource in the required implemented class.
SimpleInterfaceDao.java
package com.dao;
import java.util.List;
import com.connection.impl.QuerySpecifierWrapperList;
public interface SimpleInterfaceDao<T> {
public List<String> loadColumnNames(String query);
public List<T> loadAll(String query);
}
ClusterInfoDaoImpl.java
package com.dao.impl;
import java.util.List;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import com.common.CommonConstants;
import com.connection.impl.QueryExecutorImpl;
import com.connection.impl.QuerySpecifierWrapperList;
import com.dao.ClusterInfo;
import com.dao.SimpleInterfaceDao;
public class ClusterInfoDaoImpl <T> implements SimpleInterfaceDao <T> {
#Autowired
DataSource GlobalcashmanmdataSource;
static Logger log = Logger.getLogger(ClusterInfoDaoImpl.class.getName());
public List<T> loadAll(String query){
List<ClusterInfo> listClusterinfo = null;
log.info("Executing query loadAll:" + query);
//JdbcTemplate jdbcTemplate = (JdbcTemplate) GlobalcashmanmdataSource;
JdbcTemplate jdbcTemplate = new JdbcTemplate(GlobalcashmanmdataSource);
listClusterinfo = jdbcTemplate.query(query,new BeanPropertyRowMapper<ClusterInfo>(ClusterInfo.class));
return (List <T>) listClusterinfo;
}
public List<String> loadColumnNames(String query){
List<String> columnNames = null;
//TODO to be removed or commented once the testing is done.
//callContextToSetDataSource();
JdbcTemplate jdbcTemplate = new JdbcTemplate(GlobalcashmanmdataSource);
columnNames = jdbcTemplate.queryForList(query,String.class);
return columnNames;
}
public void insert(ClusterInfo customer){
}
}
call to the function
public class QueryExecutorImpl {
public QueryExecutionResults executeQueryWrapperByQueryID(String queryID){
......
......
SimpleInterfaceDao <ClusterInfo> daoInterface = new ClusterInfoDaoImpl<ClusterInfo>();
queryColumnNames = daoInterface.loadColumnNames(querySpecifier.getColumnQuery());
queryRowColResult = (List) daoInterface.loadAll(querySpecifier.getColumnQuery());
......
}
bean.xml
<bean id="queryexecutorimplbean" class="com.connection.impl.QueryExecutorImpl">
</bean>
Question is not clear, However you could try this way
If ClusterInfoDaoImpl bean, already been created then it's simple, inject this directly into QueryExecutorImpl (have a instance ClusterInfoDaoImpl<?> daoInterface; and it's setter property)
<bean id="queryexecutorimplbean" class="com.connection.impl.QueryExecutorImpl">
<property name="ClusterInfoDao" ref="ClusterInfoDaoImpl" />
</bean>
I think nothing much to do with templates here.

Problems with AccessReferenceMap

I am using AccessReferenceMap from OWASP to secure my ids in URLs. The problem is that when list of IDs to be obfuscated is related to particular customer. Here is my configuration:
<bean id="hyperlinkMapping" class="web.security.HyperlinkMapping" scope="session">
<aop:scoped-proxy />
</bean>
<bean id="tracksAccessMap" class="web.security.EntityAccessMap"
scope="session" factory-method="create">
<constructor-arg index="0" ref="allTrackIdsForCustomer" />
<aop:scoped-proxy/>
</bean>
<bean id="allTrackIdsForCustomer" scope="session"
factory-bean="webTrackDAO"
factory-method="findAllTrackIdsForCustomer">
<aop:scoped-proxy/>
</bean>
<bean id="webTrackDAO" class="web.repository.impl.WebTrackDAOImpl"/>
EntityAccessMap:
package web.security;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.owasp.esapi.AccessReferenceMap;
import org.owasp.esapi.errors.AccessControlException;
import org.owasp.esapi.reference.RandomAccessReferenceMap;
import org.springframework.stereotype.Component;
import core.domain.Entity;
#Component
public class EntityAccessMap<T extends Entity> implements AccessMap<T> {
private static Logger logger = Logger.getLogger(EntityAccessMap.class);
private static final long serialVersionUID = -436098952674898327L;
private AccessReferenceMap<String> map = new RandomAccessReferenceMap();
public EntityAccessMap() {
}
private EntityAccessMap(final List<T> entities) {
logger.info("Entities size: " + entities.size());
for (final T entity : entities) {
map.addDirectReference(entity);
}
}
public <T extends Entity> AccessMap<T> create(final List<T> entities) {
logger.info("calling create with entities' size " + entities.size() );
return new EntityAccessMap<>(entities);
}
public String getIndirectReference(final T entity) {
for( Iterator it = map.iterator(); it.hasNext(); ) {
logger.info((String)it.next().toString());
}
logger.info("Entity: " + map.getIndirectReference(entity));
return map.getIndirectReference(entity);
}
public T getDirectReference(final String indirectReference) {
try {
return map.getDirectReference(indirectReference);
} catch (AccessControlException e) {
throw new IllegalArgumentException("Indirect Reference is not valid", e);
}
}
}
AccessMap:
package web.security;
import java.io.Serializable;
import core.domain.Entity;
public interface AccessMap<T extends Entity> extends Serializable {
String getIndirectReference(final T entity);
T getDirectReference(final String indirectReference);
}
HyperlinkMapping:
package web.security;
import java.io.Serializable;
import org.springframework.beans.factory.annotation.Autowired;
import core.domain.track.Track;
public class HyperlinkMapping implements Serializable {
private static final long serialVersionUID = -2011016815710653498L;
#Autowired AccessMap<Track> tracksAccessMap;
public String getTrackId(final Track track) {
return tracksAccessMap.getIndirectReference(track);
}
public Track getTrack(final String indirectId) {
return tracksAccessMap.getDirectReference(indirectId);
}
}
So, what I want to achieve: tracksAccessMap should be filled only with customer's related ids, not whole set. How to initialize all these beans after customer's login (and setting customerId session attribute)?
EDIT 1: additional code:
TracksController:
package web.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import core.constants.WebConstants;
import web.service.TrackService;
#Controller
#Secured("ROLE_USER")
#RequestMapping(WebConstants.WEB_MY)
#Scope("session")
public class TracksController {
#Autowired
private TrackService trackService;
#Autowired
private HyperlinkMapping hyperlinkMapping;
#RequestMapping(value=WebConstants.WEB_MYTRACKS, method = RequestMethod.GET, produces = "application/json")
public ModelAndView showTracks( HttpServletRequest request, #RequestParam(value = "pageSize", required = false) Integer pageSize ) {
ModelAndView mv = new ModelAndView();
mv.addObject("pagedListHolder",trackService.getTracksList(request, pageSize == null ? 10 : pageSize ));
mv.addObject("hyperlinkMapping",hyperlinkMapping);
return mv;
}
}
centerColTracks.jsp
<c:forEach items="${pagedListHolder.pageList}" var="item">
<tr>
<td>${item.id}</td>
<td style="color:blue;text-align:right">${item.name}</td>
<td style="color:blue;text-align:right">${item.trackDate}</td>
<td style="color:blue;text-align:right">${item.description}</td>
</tr>
</c:forEach>
hyperlinkMapping.getTrackId(item) should return ONLY trackId (taken from AccessReferenceMap) related ONLY for customer logged in. In other words - hyperlinkMapping should be instantiated right after the login.
I have two ideas how to do this: 1. AOP with after-returning advice, or 2. use SimpleUrlAuthenticationSuccessHandler, where I can instantiate HyperlinkMapping after login. Or I can use it with the current implementation and I just simply forgot something?

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.

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

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.

NoSuchBeanDefinitionException: No matching bean of type

I'm trying some code.
It is an architecture Hibernate - JPA - Spring. For now, I will wish to run it in a JUnit test.
For moment, i have some exception :
GRAVE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#6295eb] to prepare test instance [test.service.UserAccountServiceTest#609959]
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userAccountService': Injection of autowired dependencies failed;
...
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private test.persistence.dao.UserAccountDao test.service.impl.UserAccountServiceImpl.userAccountDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [test.persistence.dao.UserAccountDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [test.persistence.dao.UserAccountDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
... 43 more
20 juil. 2012 10:56:19 test.service.UserAccountServiceTest tearDownOnce
INFO: tearDownOnce()
Here the JUnit : UserServiceTest
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
import test.jndi.ContextDatasourceCreator;
import test.persistence.entity.UserAccount;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {
"classpath:/spring/applicationContext.xml"})
public class UserAccountServiceTest extends Assert {
private static final Log LOG = LogFactory.getFactory().getInstance(UserAccountServiceTest.class);
#Autowired
#Qualifier("userAccountService")
private UserAccountService userAccountService;
#BeforeClass
public static void setUpOnce() {
LOG.info("setUpOnce()");
ContextDatasourceCreator.init();
}
#AfterClass
public static void tearDownOnce() {
LOG.info("tearDownOnce()");
}
#Before
public void onSetUp() {
LOG.info("onSetUp()");
}
#After
public void OnTearDown() {
LOG.info("OnTearDown()");
}
#Test
public void testListAll() {
List<UserAccount> allUserAccounts = userAccountService.getAllAccounts();
for (UserAccount userAccount : allUserAccounts) {
LOG.info(userAccount);
}
}
}
/ Here my applicationContext /
<!-- Annotations Scan -->
<context:annotation-config/>
<context:component-scan base-package="test.service, test.persistence" />
<!-- Entity Manager Factory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="dbrefPU" />
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Transaction Annotations -->
<tx:annotation-driven proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" />
/ Here my source code /
GenericDao Interface :
import java.util.List;
public interface GenericDao<T extends Object> {
T save(T pojo);
void remove(Class<T> classe, int id);
void delete(T pojo);
T findById(Class<T> classe, int id);
List<T> findAll(Class<T> classe);
List<T> findByQuery(String jpql);
}
Dao Interface :
import test.persistence.entity.UserAccount;
public interface UserAccountDao extends GenericDao<UserAccount> {
UserAccount findAccount(String matricule);
}
GenericDao Impl :
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import test.persistence.dao.GenericDao;
public abstract class GenericDaoImpl<T extends Object> implements GenericDao<T> {
#PersistenceContext
protected EntityManager em;
public T save(T pojo) {
return em.merge(pojo);
}
public void remove(Class<T> classe, int id) {
T pojo = findById(classe, id);
if (pojo != null) {
em.remove(pojo);
}
}
public void delete(T pojo) {
em.remove(pojo);
}
public T findById(Class<T> classe, int id) {
return (T) em.find(classe, id);
}
public List<T> findAll(Class<T> classe) {
StringBuffer jpql = new StringBuffer(20);
jpql.append("from ").append(classe.getName());
List<T> result = em.createQuery(jpql.toString()).getResultList();
return result;
}
public List<T> findByQuery(String jpql) {
List<T> result = em.createQuery(jpql).getResultList();
return result;
}
}
Dao Impl :
import javax.persistence.NoResultException;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import test.persistence.dao.UserAccountDao;
import test.persistence.entity.UserAccount;
#Repository("userAccountDao")
public class UserAccountDaoImpl extends GenericDaoImpl<UserAccount> implements UserAccountDao {
public UserAccount findAccount(String matricule) {
Query query = em.createNamedQuery("UserAccount.login");
query.setParameter("matricule", matricule);
UserAccount account = null;
try {
account = (UserAccount) query.getSingleResult();
} catch (NoResultException nre) {
}
return account;
}
}
Service interface :
import java.util.List;
import test.persistence.entity.UserAccount;
public interface UserAccountService {
public abstract UserAccount login(String matricule);
public abstract UserAccount register(String matricule);
public abstract UserAccount getAccountWithId(Integer id);
public abstract List<UserAccount> getAllAccounts();
}
Service Impl :
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import test.persistence.dao.UserAccountDao;
import test.persistence.entity.UserAccount;
import test.service.UserAccountService;
#Service("userAccountService")
#Transactional
public class UserAccountServiceImpl implements UserAccountService {
#Autowired
#Qualifier("userAccountDao")
private UserAccountDao userAccountDao;
public UserAccount getAccountWithId(Integer id) {
return userAccountDao.findById(UserAccount.class, id);
}
public UserAccount login(String matricule) {
return userAccountDao.findAccount(matricule);
}
public UserAccount register(String matricule) {
UserAccount account = new UserAccount();
account.setMatricule(matricule);
try {
account = userAccountDao.save(account);
} catch (Exception e) {
}
return account;
}
public List<UserAccount> getAllAccounts() {
return userAccountDao.findAll(UserAccount.class);
}
}
Any idea ?
Thanks a lot !!
I didn't find the solution.
In Maven, it is not working.
In dynamic web project, i succeed to execute my test if i change the #PersistenceContext to an EXTENDED.

Resources