5

i'm learning spring now. here's my sample code. i'm using jersey, spring, hibernate, and mysql for my REST service.

CustomerServiceImpl.java which is REST endpoint (partial code)

package com.samples.service.impl;

@Path("customers")
public class CustomerServiceImpl implements CustomerService {

    private static Logger logger = Logger.getLogger(CustomerServiceImpl.class);

    @Autowired
    CustomerBO customerBO;

here is CustomerBOImpl.java (partial code)

package com.samples.BO.impl;

@Component
public class CustomerBOImpl implements CustomerBO {

    @Autowired
    CustomerDAO customerDAO;

    @Autowired
    CustomerAdapter customerAdapter;

CustomerDAOImpl.class package com.samples.DAO.impl;

@Repository
public class CustomerDAOImpl implements CustomerDAO {

this is 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"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/context 
              http://www.springframework.org/schema/context/spring-context-3.0.xsd
              http://www.springframework.org/schema/tx 
              http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<context:property-placeholder location="classpath*:database.properties"/>
<context:component-scan base-package="com.samples"/>
<context:annotation-config />

</beans>    

this is first few lines of exception i'm getting.

http-bio-8090-exec-1] [class: CustomerServiceImpl] INFO  - list all customers
[http-bio-8090-exec-1] [class: CustomerServiceImpl] INFO  - customerBO is null
May 08, 2014 10:55:29 AM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NullPointerException
    at com.samples.service.impl.CustomerServiceImpl.getAllCustomers(CustomerServiceImpl.java:40)
    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:606)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvo

this is web.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
    <display-name>Employee Service</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>

        classpath*:applicationContext.xml
        </param-value>
    </context-param>

    <context-param>
        <param-name>initializeContextOnStartup</param-name> 
        <param-value>true</param-value> 
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener>

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.samples.service</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</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>

so if i'm understanding how this works correctly, i'm configuring xml to have my components autoscanned by providing the package under which i want to run autoscan. and for objects that i want to autowire. in CustomerServiceImpl class, i use @autowired for customerBO object which should have been scanned by @Component annotation on CustomerBOImpl.class definition. can you please help why my auto-scan is not picking up autowired customerBO object? thanks.

user3590506
  • 171
  • 1
  • 4
  • 16
  • i'm using spring and jersey. so i believe jersey should look for @Path to find resources? – user3590506 May 08 '14 at 18:08
  • yes i am. full implementation uses maven, spring, jersey, hibernate, c3p0, mysql. but it is still lite weight exercise for me. this is simple REST service. – user3590506 May 08 '14 at 18:13
  • Remember having to do this - see this [answer](http://stackoverflow.com/questions/19745187/spring-di-autowired-property-is-null-in-a-rest-service#19751981) – Reimeus May 08 '14 at 18:14
  • How are you instantiating the `CustomerServiceImpl`? Spring should throw an exception if it fails to autowire a dependency... – Chris Thompson May 08 '14 at 18:18
  • chris, i'm using jersey so i'm using @Path annotation for jersey to pick up the resource. i don't see any autowire dependency errors in the log. it's just that autowired bean is actually null which is my problem. – user3590506 May 08 '14 at 18:23
  • reimeus, thanks for the link. i did try using spring servlet in my web.xml but i'm still getting the same error. i added my web.xml to my original posting – user3590506 May 08 '14 at 18:23
  • Provide the code where you call this `CustomerServiceImpl#getAllCustomers` method. Otherwise, there could be several reasons for your code to throw NPE. – Luiggi Mendoza May 08 '14 at 20:29
  • http://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null – Ahmed AEFattah Aug 23 '15 at 11:21

4 Answers4

4

I suspect the problem is your CustomerServiceImpl class is being instantiated outside of Spring, either by the servlet container or explicitly in your code. You need to either have Spring instantiate it (by making it a bean, etc) or use <context:spring-configured/>. I'm not sure if the latter will work if the servlet container instantiates the object as it will likely depend on the order in which things occur...

Chris Thompson
  • 35,167
  • 12
  • 80
  • 109
  • thanks for the comment. looking at the link reimeus has provided above http://stackoverflow.com/questions/19745187/spring-di-autowired-property-is-null-in-a-rest-service#19751981 , i think you may be right. i'm using both spring and jersey. i have used spring servlet in web.xml as suggested by mentioned solution, and i already had jersey-spring dependency exclusion correctly. but still getting null for autowire. will continue to play around this solution. – user3590506 May 08 '14 at 18:32
1

Spring only know to autowire fields that have been marked as beans. From your code CustomerDAO is not a bean. For example to define it as a bean in the xml configuration file you need to add <bean id="customerDao" class="com.packagesNames.CustomerDaoImpl"/> in the xml file. or to have the class annotated with @Component or to have it defined with @Bean in a @Configuration class.

Random42
  • 8,989
  • 6
  • 55
  • 86
  • thanks for comment. i didn't post CustomerDAOImpl code, but it does have @Component annotation. the problem is actually happening earlier, where CustomerBOImpl autowiring is failing at CustomerServiceImpl. (just updated main question with CustomerDAOImpl code) also i'm trying to avoid defining bean in xml if possible. – user3590506 May 08 '14 at 18:15
1

Jersey 2 and Spring integration is now supported.

Jersey Docs: Chapter 22. Spring DI

Blog: Implementing Jersey 2 Spring Integration

Sample App: Jersey's Hello World Spring WebApp

However, as of this writing, Spring beans can't be injected directly into JAX-RS classes by using Spring XML configuration. Annotations (@Autowired, etc.) must be used.

Victor Lyuboslavsky
  • 9,882
  • 25
  • 87
  • 134
0

I had the same problem. My injected bean in the resource class was always coming as NULL.

I spent 2 days trying to figure it out why I can't inject the Spring Bean into the JAX-RS resource class. Then I found the below in the Jersey documentation:

"Limitations:

Spring beans can't be injected directly into JAX-RS classes by using Spring XML configuration"

Note: I was using Jersey 2 and Spring 3.x in my project.

Unheilig
  • 16,196
  • 193
  • 68
  • 98
Sumit
  • 119
  • 2
  • 7