How to get DataSource bean from config in the Junit5 - spring

Dears,
I have created a junit5 test case ( UserDaoTests.java) but I am not able to get DataSource Bean defined in the spring configuration file (data.xml).
Project Structure:
test cases are defined in test/com/caveofprogramming/spring/test/tests package, UserDaoTests.java class.
data.xml
configuration file for junit. I have defined datasource bean in it.
<?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"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.3.xsd">
<context:component-scan
base-package="com.caveofprogramming.spring.test.tests">
</context:component-scan>
<context:annotation-config></context:annotation-config>
<mvc:annotation-driven></mvc:annotation-driven>
<context:property-placeholder
location="test/com/caveofprogramming/spring/test/config/jdbc.properties" />
<beans profile="dev">
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="username" value="${jdbc.username}"></property>
</bean>
</beans>
</beans>
jdbc.properties:
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:#(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = TESTD01)))
jdbc.password=1234
jdbc.username=offerTest
Junit test(UserDaoTests.java)
package com.caveofprogramming.spring.test.tests;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import com.offers.DAO.UserDAO;
#ActiveProfiles("dev")
#ContextConfiguration(locations = {
"classpath:test/com/caveofprogramming/spring/test/config/data.xml",
"classpath:com/offers/config/offerDAO-context.xml",
"classpath:com/offers/config/offerService-context.xml" })
public class UserDaoTests {
#Autowired
private UserDAO userDao;
private static DataSource dataSource;
private JdbcTemplate jdbc;
#Autowired
public UserDaoTests() {
ApplicationContext context = new FileSystemXmlApplicationContext("test/com/caveofprogramming/spring/test/config/data.xml");
this.dataSource = (DataSource) context.getBean("dataSource");
}
#Test
public void testCreateUser() {
if ( dataSource == null) {
System.out.println("DataSource is null");
}
else {
System.out.println("DataSource is not null!!!! ");
}
}
}
Logs:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'dataSource' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:816)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1288)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
I would also like to clarify that I am using static DataSource because I need to use #BeforeAll, which require static fields only.
I have tested for non static Data Source as well but result is still the same.
--Update----
I removed <beans profile="dev"> tag from data.xml config file and it's working fine. But I don't understand why it's not working with profile.
--- Update 2 ( Update on on Bhushan's answer) -----
UserDaoTests - updated code
#ExtendWith(SpringExtension.class)
//Add all required depency xml
#ContextConfiguration(locations = { "classpath:test/com/caveofprogramming/spring/test/config/data.xml",
"classpath:com/offers/config/offerDAO-context.xml",
"classpath:com/offers/config/offerService-context.xml" })
#ActiveProfiles("dev")
public class UserDaoTests {
#Autowired
private UserDAO userDao;
#Autowired
private DataSource dataSource;
#Autowired
private JdbcTemplate jdbc;
#Test
public void testCreateUser() {
Assertions.assertNotNull(dataSource);
// Assertions.assertNotNull(jdbc);
}
}
Error Stacktrace:
org.opentest4j.AssertionFailedError: expected: not <null>
at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39)
at org.junit.jupiter.api.Assertions.fail(Assertions.java:109)
at org.junit.jupiter.api.AssertNotNull.failNull(AssertNotNull.java:47)
at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:36)
at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:31)
at org.junit.jupiter.api.Assertions.assertNotNull(Assertions.java:283)
at com.caveofprogramming.spring.test.tests.UserDaoTests.testCreateUser(UserDaoTests.java:38)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:43)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:82)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:73)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:141)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

Here you are creating multipe application context, one is creating with #ContextConfiguration and another one with FileSystemXmlApplicationContext, so avoid FileSystemXmlApplicationContext and update your code following
#ExtendWith(SpringExtension.class)
//Add all required depency xml
#ContextConfiguration(locations = {
"classpath:test/com/caveofprogramming/spring/test/config/data.xml",
"classpath:com/offers/config/offerDAO-context.xml",
"classpath:com/offers/config/offerService-context.xml" })
#ActiveProfiles("dev")
public class UserDaoTests {
#Autowired
private UserDAO userDao;
#Autowired
private DataSource dataSource;
#Autowired
private JdbcTemplate jdbc;
#Test
public void testCreateUser() {
Assertions.assertNotNull(dataSource);
Assertions.assertNotNull(jdbc);
}
}
Also avoid #BeforeAll as its coupled with static memory, and ours Beans are managed by spring so can't go with it, instead of it you can you for #BeforeEach and if you want perform some logic witch you want run only once for all test cases so you can do hack something like
private AtomicBoolean executed = new AtomicBoolean(false);
#BeforeEach
public void runOnce() {
if(!executed.getAndSet(true)) {
// write you logic which you want will run only once for all test cases
}
}

Related

how can we build a spring mvc multitenant application using hibernate as orm separate database and schema

from spring io u shifted to stack overflow but nowhere u have explained about multitenant complete demo application which can be seen as a problem solver infact no one seen satisfied with ur answers can u please now share a working demo of multitenant schema and separate database complete code anywhere where people can use it kindly
package com.domain.model;
import javax.persistence.*;
#Entity
#Table
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int employeeId;
#Column
private String employeeName;
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
}
package com.domain.multitenancy;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class CurrentTenantIdentifierResolverimpl implements CurrentTenantIdentifierResolver {
#Override
public String resolveCurrentTenantIdentifier() {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String tenantId = attr.getRequest().getParameter("tenantId");
return tenantId;
}
#Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
package com.domain.multitenancy;
import com.domain.master.MasterService;
import org.hibernate.service.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
import javax.sql.DataSource;
public class MultiTenantConnectionprovideImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
#Override
protected DataSource selectAnyDataSource() {
return MasterService.getDataSourceHashMap().get("tenantId1");
}
#Override
protected DataSource selectDataSource(String tenantIdentifier) {
return MasterService.getDataSourceHashMap().get(tenantIdentifier);
}
}
package com.domain.master;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.util.HashMap;
public class MasterService {
public static HashMap<String, DataSource> getDataSourceHashMap() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/multiten");
dataSource.setUsername("root");
dataSource.setPassword("root");
DriverManagerDataSource dataSource1 = new DriverManagerDataSource();
dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
dataSource1.setUrl("jdbc:mysql://localhost:3306/multiten_1");
dataSource1.setUsername("root");
dataSource1.setPassword("root");
HashMap hashMap = new HashMap();
hashMap.put("tenantId1", dataSource);
hashMap.put("tenantId2", dataSource1);
return hashMap;
}
}
<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:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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">
<context:component-scan base-package="com.domain"/>
<mvc:annotation-driven/>
<context:property-placeholder location="classpath:application.properties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="packagesToScan">
<list>
<value>com.domain.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
<prop key="hibernate.multiTenancy">DATABASE</prop>
<prop key="hibernate.tenant_identifier_resolver">com.domain.multitenancy.CurrentTenantIdentifierResolverimpl</prop>
<prop key="hibernate.multi_tenant_connection_provider">com.domain.multitenancy.MultiTenantConnectionprovideImpl</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
#Application.properties file in classpath
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/multiten
jdbc.username = root
jdbc.password = root
hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql = true
hibernate.format_sql = false
I have taken this example
these are the errors i got:
org.springframework.web.util.NestedServletException: Request
processing failed; nested exception is
org.springframework.transaction.CannotCreateTransactionException:
Could not open Hibernate Session for transaction; nested exception is
org.hibernate.HibernateException: SessionFactory configured for
multi-tenancy, but no tenant identifier specified
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is
org.hibernate.HibernateException: SessionFactory configured for
multi-tenancy, but no tenant identifier specified
org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:544)
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
com.sun.proxy.$Proxy22.save(Unknown Source)
com.domain.controller.EmployeeController.saveEmployee(EmployeeController.java:35)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
org.hibernate.HibernateException: SessionFactory configured for multi-tenancy, but no tenant identifier specified
org.hibernate.internal.AbstractSessionImpl.(AbstractSessionImpl.java:85)
org.hibernate.internal.SessionImpl.(SessionImpl.java:239)
org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1618)
org.hibernate.internal.SessionFactoryImpl.openSession(SessionFactoryImpl.java:978)
org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:436)
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
com.sun.proxy.$Proxy22.save(Unknown Source)
com.domain.controller.EmployeeController.saveEmployee(EmployeeController.java:35)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.
Session for transaction; nested exception is
org.hibernate.HibernateException: SessionFactory configured for
multi-tenancy, but no tenant identifier specified
The above error suggests that tenant identifier is not specified. Please double check your configuration and the identifier class implementation name.
The reason you are getting this error is that your tenant identifier resolver needs to return something default in case it cannot find appropriate tenant id from the strategy you have chosen ( in your case you are trying to get the tenant id from request params). I have used the updated code below and it is no longer showing the error.
public class CurrentTenantIdentifierResolverimpl implements CurrentTenantIdentifierResolver {
#Override
public String resolveCurrentTenantIdentifier() {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String tenantId = attr.getRequest().getParameter("tenantId");
if (tenantId==null) {
//return default tenant
return "tenantId1";
}
return tenantId;
}
#Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
Shailendra sir how can we set a tenant id to it without setting default id and get the username from spring security and pass it to the tenant id

Spring/MongoDB/Junit: Unit test with Fongo is giving the Null Pointer Exception

I am fairly new to unit testing and trying to test a simple function that returns a query. In my unit test, I am getting the NullPointerException after calling the method. I assume mongoOperations is null, and guessing that is the reason why it is returning NPE. I am using fongo to mock the mongoDB and I configured the spring context in testConfigurationContext.xml file.
This is the class I want to test:
#Repository
public class DataVersionDaoMongo extends MongoBaseDao<DataVersion> implements DataVersionDao {
public DataVersionDaoMongo() {
initType();
}
#Override
public DataVersion
findByDBAndCollection(String dbName, String collectionName) {
//below is the line 27 on error console
return mongoOperations.findOne(Query.query(Criteria.where("dbName").is(dbName).and("collectionName").is(collectionName)), DataVersion.class);
}
}
This is my unit test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:/testApplicationContext.xml")
public class DataVersionDaoMongoTest {
private DataVersionDaoMongo dataVersionDaoMongo = new DataVersionDaoMongo();
private MongoOperations mongoOperations;
private DataVersion dataVersion;
#Rule
public FongoRule fongoRule = new FongoRule();
#Test
public void findByDBAndCollection() {
String dbname = "mydb";
String collectionName = "mycollection";
DB db = fongoRule.getDB(dbname);
DBCollection collection = db.getCollection(collectionName);
Mongo mongo = fongoRule.getMongo();
collection.insert(new BasicDBObject("name", "randomName"));
//below is the line 63 on error console
assertThat(dataVersionDaoMongo.findByDBAndCollection(dbname, collectionName)).isNotNull();
}
}
This is the applicationContext file:
<?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:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
<bean name="fongo" class="com.github.fakemongo.Fongo">
<constructor-arg value="InMemoryMongo" />
</bean>
<bean id="mongo" factory-bean="fongo" factory-method="getMongo" />
<mongo:db-factory id="mongoDbFactory" mongo-ref="mongo" />
<!-- localhost settings for mongo -->
<!--<mongo:db-factory id="mongoDbFactory" />-->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory"/>
</bean>
</beans>
This is the error on console:
java.lang.NullPointerException
at com.absolute.common.repository.mongodb.springdata.DataVersionDaoMongo.findByDBAndCollection(DataVersionDaoMongo.java:27)
at com.absolute.common.repository.mongodb.springdata.DataVersionDaoMongoTest.findByDBAndCollection(DataVersionDaoMongoTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
I am guessing I am missing something. Any help would be greatly appreciated!
I have never used Fongo, but usually I mock the mongo server with flapdoodle. This is easy to implements.
I would like to recommend it.
https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>2.1.1</version>
<scope>test</scope>
</dependency>
You are not auto-wiring DataVersionDaoMongo in you unit test, also mongoOperations bean either need to be auto-wired or injected via constructor.
In you Repo class
#Repository
public class DataVersionDaoMongo extends MongoBaseDao<DataVersion> implements DataVersionDao {
#Autowire MongoOperations mongoOperations;
public DataVersionDaoMongo() {
initType();
}
#Override
public DataVersion findByDBAndCollection(String dbName, String collectionName) {
//below is the line 27 on error console
return mongoOperations.findOne(Query.query(Criteria.where("dbName").is(dbName).and("collectionName").is(collectionName)), DataVersion.class);
}
}
and in your unit test, you no need to use new for bean creation.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:/testApplicationContext.xml")
public class DataVersionDaoMongoTest {
#Autowire
private DataVersionDaoMongo dataVersionDaoMongo;
#Autowire
private MongoOperations mongoOperations; // you can remove this, if not using it
private DataVersion dataVersion;
#Rule
public FongoRule fongoRule = new FongoRule();
#Test
public void findByDBAndCollection() {
String dbname = "mydb";
String collectionName = "mycollection";
DB db = fongoRule.getDB(dbname);
DBCollection collection = db.getCollection(collectionName);
Mongo mongo = fongoRule.getMongo();
collection.insert(new BasicDBObject("name", "randomName"));
//below is the line 63 on error console
assertThat(dataVersionDaoMongo.findByDBAndCollection(dbname, collectionName)).isNotNull();
}
}

I am getting error in spring Dao while data insert : Warning: servlet spring threw exception java.lang.NullPointerException

I am new to spring just learning to insert data into oracle database I created a web project seeing few tutorials and created all necessary steps but while running I got this error mentioned in bellow your help is appreciated.
Spring-servlet.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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd ">
<context:annotation-config />
<context:component-scan base-package="com.x"/>
<!-- Getting Database properties -->
<context:property-placeholder location="classpath:connectDb.properties" />
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
id="dataSource">
<property name="driverClassName" value="${database.driver}"></property>
<property name="url" value="${database.url}"></property>
<property name="username" value="${database.user}"></property>
<property name="password" value="${database.password}"></property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>nowpro1</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
AnotherFormController.java
package com.x;
import com.x.dao.EmpDao;
import com.x.model.Emp;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class AnotherFormController {
//public EmpDao dao;
#RequestMapping("/")
public ModelAndView homeMethod() {
// System.out.println("Hello World");
String Mess = "Another Abstract Controller Test";
ModelAndView modelAndView = new ModelAndView("index");
modelAndView.addObject("message", Mess);
return modelAndView;
}
#RequestMapping(value="/welcome", method=RequestMethod.POST)
public ModelAndView CtrlMethod(#ModelAttribute("employee1") Emp employee1) {
ModelAndView model = new ModelAndView("hellopage");
EmpDao dao = new EmpDao();
dao.insertData(new Emp(104,"Jenish","jenish#gmail.com","9445807204"));
System.out.println(employee1.getEname());
return model;
}
}
Emp.java
package com.x.model;
public class Emp {
private int Eid;
private String Ename;
private String Mobile;
private String Email;
public int getEid() {
return Eid;
}
public void setEid(int Eid) {
this.Eid = Eid;
}
public String getEname() {
return Ename;
}
public void setEname(String Ename) {
this.Ename = Ename;
}
public String getMobile() {
return Mobile;
}
public void setMobile(String Mobile) {
this.Mobile = Mobile;
}
public String getEmail() {
return Email;
}
public void setEmail(String Email) {
this.Email = Email;
}
public Emp(){
}
public Emp(int Eid,String Ename,String Mobile,String Email) {
setEid(Eid);
setEname(Ename);
setMobile(Mobile);
setEmail(Email);
}
}
EmpDao.java
package com.x.dao;
import com.x.model.Emp;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class EmpDao {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public DataSource getDataSource() {
return dataSource;
}
#Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void insertData(Emp emp) {
String sql = "insert into Emp (Eid,Ename,Mobile,Email) values(?,?,?,?)";
jdbcTemplate.update(sql, new Object[] {emp.getEid(),emp.getEname(),emp.getMobile(),emp.getEmail()});
}
}
My Error
Warning: StandardWrapperValve[spring]: Servlet.service() for servlet spring threw exception
java.lang.NullPointerException
at com.x.dao.EmpDao.insertData(EmpDao.java:39)
at com.x.AnotherFormController.CtrlMethod(AnotherFormController.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:177)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:434)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:748)
NullPointerException is a clear exception. It seems that the exception is not related to Spring Dao. Set break point at the start of insertData method. I think emp is null so when you call getters of fields of Emp you get NullPointerException.

#Component Springs annotation not working

I am using Springs framework 3.2.0. and i am not able to use #component annotation. Below is the error which i received when Test.java was executed.
I tried changing the java version, and springs framework version but nothing worked.
Beans.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:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="util-namespace"
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">
<context:annotation-config />
<context:component-scan base-package="com.ds.cab.car" />
<bean id="e" class="com.ds.cab.engine.Engine">
<property name="modelyear" value="2015 AUDI"></property>
</bean>
</beans>
Car.java
package com.ds.cab.car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ds.cab.engine.Engine;
#Component
public class Car {
#Autowired
private Engine engine;
public void setEngine(Engine engine) {
this.engine = engine;
}
public void printData() {
// TODO Auto-generated method stub
System.out.println("Engine model year: "+engine.getModelyear());
}
}
Engine.java
package com.ds.cab.engine;
public class Engine {
private String modelyear;
public void setModelyear(String modelyear) {
this.modelyear = modelyear;
}
public String getModelyear() {
return modelyear;
}
}
Test.java
package ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ds.cab.car.Car;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("Beans.xml");
Car c = (Car)ctx.getBean(Car.class);
c.printData();
}
}
Error
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file [E:\Prakhar\STS Workspace\StereoTyping01\bin\com\ds\cab\car\Car.class]; nested exception is java.lang.IllegalArgumentException
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:281)
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:242)
at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:84)
at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:73)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1435)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1425)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:140)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:111)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:451)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at ioc.Test.main(Test.java:10)
Caused by: java.lang.IllegalArgumentException
at org.springframework.asm.ClassReader.<init>(Unknown Source)
at org.springframework.asm.ClassReader.<init>(Unknown Source)
at org.springframework.asm.ClassReader.<init>(Unknown Source)
at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:52)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:80)
at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:101)
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:257)
... 24 more
Create a Car bean and inject your engine bean into it (e represents your engine bean name):
<bean id="Car" class = "com.ds.cab.car.Car">
<constructor-arg ref="e"/>
</bean>
In your beans.xml,
Change component-scan into
<context:component-scan base-package="com.ds.cab.car" />
Remove engine bean declarion.
Add #Component annotation to Car Class.

NPE when invoking getter of managed property

I am learning Spring with Hibernate and am creating a movie rental application using JSF as front end framework.
I have an application scoped managed property in my registration bean which is view scoped. In the register() method to insert the user details in the database, I invoke the service locator implementation bean to get a reference to the required service implementation. However, I get an NPE when I invoke the getter of the service locator property.
Following are my managed beans...
Registration Bean
#ManagedBean
#ViewScoped
public class RegistrationBean extends BaseBean implements Serializable
{
private static final long serialVersionUID = -6449858513581500971L;
private String userID;
private String password;
private String firstName;
private String lastName;
private String email;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String pincode;
public RegistrationBean() {
super();
}
// getter / setters...
public String register()
{
String nextPage = null;
try {
RegistrationDetails userDetails = ModelBuilder.populateRegistrationData(this);
// NPE at this line. getServiceLocator() returns null
int registrationID = getServiceLocator().getUserService().registerUser(userDetails);
nextPage = "success";
}
catch (RegistrationException e) {
LOGGER.error(e.getMessage());
}
return nextPage;
}
}
Base Bean
public class BaseBean
{
#ManagedProperty("#{serviceLocator}")
protected IServiceLocator serviceLocator;
protected IServiceLocator getServiceLocator() {
return serviceLocator;
}
public void setServiceLocator(IServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}
Service Locator Bean
#ManagedBean
#ApplicationScoped
public class ServiceLocator implements IServiceLocator
{
private static final String USER_SERVICE = "userService";
public ServiceLocator() {
super();
final ServletContext sc = FacesUtils.getServletContext();
this.webAppContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
this.userService = (IUserService) webAppContext.getBean(USER_SERVICE);
}
private ApplicationContext webAppContext;
private IUserService userService;
#Override
public IUserService getUserService() {
return userService;
}
public ApplicationContext getWebAppContext() {
return webAppContext;
}
}
And here is the stacktrace as seen in my Eclipse console
Oct 14, 2012 10:28:39 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: #{registrationBean.register}: java.lang.NullPointerException
javax.faces.FacesException: #{registrationBean.register}: java.lang.NullPointerException
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 23 more
Caused by: java.lang.NullPointerException
at com.clixflix.managedbeans.RegistrationBean.register(RegistrationBean.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 24 more
I am using
JSF 2.1 (Mojarra)
Hibernate 4.1
Spring 3.2
Tomcat 7
Eclipse 3.7
Could someone please point out if I have missed something??
UPDATE: Spring config file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation" value="/WEB-INF/hibernate.cfg.xml" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="userDAO" class="com.clixflix.dao.impl.UserDAOImpl">
<constructor-arg index="0" ref="hibernateTemplate" />
</bean>
<bean id="userService" class="com.clixflix.services.impl.UserService">
<constructor-arg index="0" ref="userDAO" />
</bean>
</beans>
This post helped me to make the code work : http://www.javacodegeeks.com/2012/04/jsf-2-primefaces-3-spring-3-hibernate-4.html
However, the code does not work if I keep the Registration Bean as view scoped. Can anyone please help me figure out the reason for the same?
UPDATE: Found the solution for the ViewScope issue : http://blog.harezmi.com.tr/spring-view-scope-for-jsf-2-users/

Resources