Jersey + Spring 3 + Maven 3 + Tomcat 7 @Resource in the @Component class are always null

I searched and tried everything I can think of to fix this, but the Dao in the TestService class is always null. I see Spring logs showing that Dao is being introduced, as well as the TestService class. I tried working under WTP for eclipse, and also directly in Tomcat. Both results lead to the same error. Can someone help decrypt where the error that causes Dao to be null in the TestService class.

Versions:

Jersey 1.8 Spring 3.0.5Release Tomcat apache-tomcat-7.0.27 Maven 3.0.3 (r1075438; 2011-02-28 12:31:09-0500) Java 1.6.0_31 Eclipse Java EE IDE for Web Developers. Version: Indigo Service Release 2 Build id: 20120216-1857 

Logging - Displays the injection process (Short for DEBUG and ClassNames for short)

  Creating shared instance of singleton bean 'dataSource' Creating instance of bean 'dataSource' Eagerly caching bean 'dataSource' to allow for resolving potential circular references Finished creating instance of bean 'dataSource' Creating shared instance of singleton bean 'jdbcTemplate' Creating instance of bean 'jdbcTemplate' Eagerly caching bean 'jdbcTemplate' to allow for resolving potential circular references Returning cached instance of singleton bean 'dataSource' Invoking afterPropertiesSet() on bean with name 'jdbcTemplate' Finished creating instance of bean 'jdbcTemplate' Creating shared instance of singleton bean 'testClassDao' Creating instance of bean 'testClassDao' Found injected element on class [test.dao.TestClassDao]: AutowiredMethodElement for public void test.dao.TestClassDao.setDataSource(javax.sql.DataSource) Eagerly caching bean 'testClassDao' to allow for resolving potential circular references Processing injected method of bean 'testClassDao': AutowiredMethodElement for public void test.dao.TestClassDao.setDataSource(javax.sql.DataSource) Returning cached instance of singleton bean 'dataSource' Autowiring by type from bean name 'testClassDao' to bean named 'dataSource' Finished creating instance of bean 'testClassDao' Creating shared instance of singleton bean 'testService' Creating instance of bean 'testService' Found injected element on class [test.service.admin.TestService]: AutowiredFieldElement for test.dao.TestClassDao test.service.admin.TestService.dao Eagerly caching bean 'testService' to allow for resolving potential circular references Processing injected method of bean 'testService': AutowiredFieldElement for test.dao.TestClassDao test.service.admin.TestService.dao Returning cached instance of singleton bean 'testClassDao' Autowiring by type from bean name 'testService' to bean named 'testClassDao' Finished creating instance of bean 'testService' 

Error - Null Pointer exception in TestService.java, because TestClassDao is null

 Apr 25, 2012 9:07:04 PM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [jersey] in context with path [/test-service] threw exception java.lang.NullPointerException at test.service.admin.TestService.createCompanyProfile(TestService.java:35) 

TestClassDao.java

 package test.dao; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Repository; import test.domain.TestClass; @Repository public class TestClassDao { private NamedParameterJdbcTemplate namedParamJdbcTemplate; private DataSource dataSource; @Autowired public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; this.namedParamJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); } public void insertTestClass(TestClass testClass) { String query = "INSERT INTO TEST_CLASS_TABLE(NAME) VALUES (:NAME)"; MapSqlParameterSource namedParams = new MapSqlParameterSource(); mapParams(namedParams, testClass); namedParamJdbcTemplate.update(query, namedParams); } private void mapParams(MapSqlParameterSource namedParams, TestClass testClass) { namedParams.addValue("NAME", testClass.getName()); } } 

TestClass.java

  package test.domain; import java.util.Date; import java.util.HashSet; import java.util.Set; public class TestClass implements java.io.Serializable { private String name; public TestClass(String name){ this.name = name; } public String getName() { return this.name; } } 

TestService.java

 package test.service.admin; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.Request; import javax.ws.rs.core.UriInfo; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import test.dao.TestClassDao; import test.domain.TestClass; @Path("/resttest") @Component public class TestService { @Context UriInfo uriInfo; @Context Request request; @Autowired TestClassDao dao; static Logger log = Logger.getLogger(TestService.class); @GET @Path("/test") public String createCompanyProfile() { TestClass test = new TestClass("MyTestName"); dao.insertTestClass(test); return "test done"; } } 

applicationContext.xml

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:1234/testClassDatabase" /> <property name="username" value="user" /> <property name="password" value="password" /> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean> <context:component-scan base-package="test"/> </beans> 

web.xml

 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>jersey</servlet-name> <servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> 

UPDATE: this is added for the web application, but nothing has changed

 <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 

pom.xml - I think it could be a problem, a dependency or something

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>test-service</groupId> <artifactId>test-service</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>Test Service</name> <url>http://maven.apache.org</url> <dependencies> <!-- Jersey --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>${jersey.version}</version> </dependency> <!-- Spring 3 dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework.version}</version> </dependency> <!-- Jersey + Spring --> <dependency> <groupId>com.sun.jersey.contribs</groupId> <artifactId>jersey-spring</artifactId> <version>${jersey.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> </dependencies> <build> <finalName>test-service</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <properties> <org.springframework.version>3.0.5.RELEASE</org.springframework.version> <jersey.version>1.8</jersey.version> </properties> </project> 

UPDATE FIXED: My friend looked and noticed that I did not have a parameter for com.sun.jersey.config.property.packages as soon as we added that everything is automated.

 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:server-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>jersey-serlvet</servlet-name> <servlet-class> com.sun.jersey.spi.spring.container.servlet.SpringServlet </servlet-class> <init-param> <param-name> com.sun.jersey.config.property.packages </param-name> <param-value>service</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-serlvet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> 
+6
source share
2 answers

Spring introduces an instance of TestService with a DAO, but this instance is not the one that the requests are accessing. You use the Jersey ServletContainer to host your application in Jersey, which does not integrate with Spring. It will create instances as necessary by themselves, which obviously will not be inserted using Spring (without any weaving of bytecode). I would recommend using SpringServlet , which is a ServletContainer that knows how to get resource classes from a Spring context. This will fix your problem.

+7
source

Same as Ryan, your ServletContainer servlet doesn't know about the Spring container, so your @Resource / @Autowired never gets any dependencies.

Use a SpringServlet instead, adding it to web.xml` or adding it to your Spring WebInitializer, not both. See examples below.

Here is sample code for web.xml :

 <servlet> <servlet-name>jersey-spring</servlet-name> <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>jersey-spring</servlet-name> <url-pattern>/resources/*</url-pattern> <load-on-startup>1</load-on-startup> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>phonebook.rest</param-value> </init-param> </servlet-mapping> 

Here is the sample code for your custom WebInitializer :

 public class PhonebookApplicationWebInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext factory = new AnnotationConfigWebApplicationContext(); // factory.scan("phonebook.configuration"); factory.register(PhonebookConfiguration.class); ServletRegistration.Dynamic dispatcher = container.addServlet("jersey-spring", new SpringServlet()); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/resources/*"); dispatcher.setInitParameter("com.sun.jersey.config.property.packages", "phonebook.rest"); container.addListener(new ContextLoaderListener(factory)); } } 

You can see a good example for Spring + Jersey integration here: http://www.mkyong.com/webservices/jax-rs/jersey-spring-integration-example/

0
source

Source: https://habr.com/ru/post/914178/


All Articles