1
votes

I'm having some issues trying to configure an app to use RESTEasy + Spring 3 + Maven. So far this is what I have:

Service interface:

package com.test.service;
public interface ProcessRequestService {
    String test();
}

Service Implementation:

package com.test.service;
import org.springframework.stereotype.Service;

@Service
public class ProcessRequestServiceImpl implements ProcessRequestService {
    @Override
    public String test() {
        return "Resteasy Test";
    }
}

Component:

package com.test.web;

@Component
@Path("/message")
public class Main {

    @Autowired
    private ProcessRequestService processRequestService;

    public void setService(ProcessRequestService processRequestService) {
        this.processRequestService = processRequestService;
    }

    @GET
    @Path("/example")
    public Response example() {
        String result = processRequestService.test();
        return Response.status(200).entity(result).build();
    }
}

My pom.xml:

<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>com</groupId>
    <artifactId>test</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>test</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>3.2.8.RELEASE</spring.version>
        <resteasy.version>3.0.4.Final</resteasy.version>
    </properties>

    <repositories>
        <repository>
            <id>JBoss repository</id>
            <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>${resteasy.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>client</finalName>
    </build>

</project>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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_3_0.xsd"
    version="3.0" metadata-complete="true">

    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/api</param-value>
    </context-param>

    <listener>
        <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>

    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

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

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>

</web-app>

And finally mvc-dispatcher.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-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.test" />
    <context:annotation-config />

</beans>

What I'm trying to avoid is to declare many beans in an xml file by using the @Service annotation.

When I deploy this application to jboss 6.1 I get a NullPointerException. I guess it is because Spring is not able to Autowire the service to the Component but I'm not sure why this is happening.

I was able to achieve this by making some modifications to this tutorial but it is using Spring's RequestMapping instead of RESTEasy.

Any help will be appreciated.

2
You can use Apache CXF implementation of JAX-RS which supports Spring. There probably will not be any code changes.Ostap Maliuvanchuk

2 Answers

1
votes

I had the same issue.please try this.

In POM file add the below dependency:

<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-spring</artifactId>
<version>3.0.4.Final</version>
</dependency>

And in mvc-dispatcher.servlet.xml add the bean definition above component-scan

<bean class="org.jboss.resteasy.plugins.spring.SpringBeanProcessorServletAware"/>

This will solve the null pointer exception.Hope this helps.

0
votes

What I'm trying to avoid is to declare many beans in an xml file by using the @Service annotation

What you are doing is fine. Mapping from annotations instead of XML is not what is giving you the NullPointerException.

When I deploy this application to jboss 6.1 I get a NullPointerException. I guess it is because Spring is not able to Autowire the service to the Component but I'm not sure why this is happening

Yes, JBoss is not able to inject because JAX-RS (in your case RESTEasy) does not know about Spring beans. They are not integrated out of the box.

It is happening because the JAX-RS implementation wont look from @Autowired in its resources (resources in this context are @Path annotated classes).

You need extra work for using Spring Beans inside a Java EE container.

Any help will be appreciated

All the options you have that I could find are:

I didnt test these examples btw. Another options are:

  • Just go with Spring MVC as you mentioned.
  • Use EJB instead of Spring Beans, which would make sense since you are under a Java EE server.
  • Maybe try Jersey.

Keep in mind that Spring's Transaction is independant from Java EE transaction. You are mixing JAX-RS with Spring. Transaction will need extra love.

If I were you I would consider using EJB instead of Spring Beans if it is an option.

I'm having some issues trying to configure an app to use RESTEasy + Spring 3 + Maven

Check out another answer of mine about this topic. Maybe it will help you decide which engine of RESTful is more appropriate for your solution.

Spring annotations for GET requests