I am having an issue integrating a simple Spring setup with RESTEasy and I
saw where version 2.3.2.Final addressed this issue under
RESTEASY-511<https://issues.jboss.org/browse/RESTEASY-511>.
The comment at the end of the trail indicated that a fix was made but did
not know how to recreate the issue and had nothing to test against. In
stepping thru the updated code -- the primary area of correction looks
correct but it is never called. Last night I posted a self-contained
project. Today I am posting a git patch for the resteasy-spring module that
adds a test to recreate the issue I am having.
git format-patch origin/Branch_2_3 --stdout > spring-javaconfig-test.patch
My large post last night is being held up because of size constraints. I
will repeat some of the key aspects here.
My project has three testing environments
a) local JUnit testing using Spring 3.1.1.RELEASE with JavaConfig - works
b) JBoss 7 integration testing with RESTEasy 2.3.2.Final cargo and
HttpClient - works
c) local development using Spring, JavaConfig, and RESTEasy - does not work
Within the problem jetty environment where I attempt to integrate Spring,
JavaConfig, and RESTEasy, I get Spring correctly instantiating, injecting,
and initializing my JSR-330 annotated POJOs. When I make a call to a
RESTEasy resource -- RESTEasy instantiates a separate copy of the classes
Spring created, does not do injection etc. (expected), and fails because of
non-injected objects.
Here is a snippet of my @Configuration class
@Configuration
@PropertySource("classpath:/test.properties")
public class HelloTestConfig {
...
@Bean @Singleton
public HelloResource helloResource() {
log.debug("creating simple POJO for helloResource");
HelloResource resource=new HelloResource();
return resource;
}
@Bean @Singleton
public HelloService helloService() {
log.debug("creating simple POJO for helloService");
return new HelloServiceImpl();
}
The following shows the HelloResource to HelloService relationship
@Path("") //results in a base URI of /rest depending on ApplicationPath
public class HelloResource {
protected @Inject HelloService impl;
@Path("hello") //results in a URI of /rest/hello depending on
ApplicationPath
@GET
@Produces(MediaType.TEXT_PLAIN) //returns text/plain MIME type
public String sayHelloREST(
@QueryParam("name") String name) {
return impl.sayHello(name);
}
The jetty web.xml is in compliance with posted examples and can be found in
the .zip file under the src/test/resources directory.
In studying the Git changes and stepping thru the RESTEasy 2.3.2.Final
SpringBeanProcessor code I found the improved getBean() method was not
being called due to a check in postProcessBeanFactory()
BeanDefinition beanDef = beanFactory.getBeanDefinition(name);
if (*beanDef.getBeanClassName()* == null || beanDef.isAbstract())
continue;
processBean(beanFactory, dependsOnProviders, name, beanDef);
If I comment out the beanClassName check processBean() gets called, the new
logic gets executed, and things work.
BeanDefinition beanDef = beanFactory.getBeanDefinition(name);
if (*/*beanDef.getBeanClassName() == null || */*
beanDef.isAbstract())
continue;
processBean(beanFactory, dependsOnProviders, name, beanDef);
I am not saying the above change is a correct fix -- it just made my
application deployment work. In fact, with the above change many/most of
the Spring unit tests fail -- so clearly there is more to this.
thanks,
jim
--
jim stafford
SRA I&S | JHU
From 9df38ca3af13059a16a23eb3dce1cdf65c1adea7 Mon Sep 17 00:00:00 2001
From: Jim Stafford <jcst...@apl.jhu.edu>
Date: Sat, 3 Mar 2012 17:19:49 -0500
Subject: [PATCH] added a testcase the demonstrates the JavaConfig issue
---
.../spring/beanprocessor/ServerConfiguration.java | 1 +
.../test/javaconfig/JavaConfigApplication.java | 8 +++
.../spring/test/javaconfig/JavaConfigResource.java | 33 +++++++++++++
.../spring/test/javaconfig/JavaConfigService.java | 10 ++++
.../spring/test/javaconfig/JavaConfigTest.java | 45 ++++++++++++++++++
.../spring/test/javaconfig/TestConfig.java | 19 ++++++++
.../src/test/resources/javaconfig/WEB-INF/web.xml | 49 ++++++++++++++++++++
.../src/test/resources/javaconfig/index.html | 8 +++
8 files changed, 173 insertions(+), 0 deletions(-)
create mode 100644 resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigApplication.java
create mode 100644 resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigResource.java
create mode 100644 resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigService.java
create mode 100644 resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigTest.java
create mode 100644 resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/TestConfig.java
create mode 100644 resteasy-spring/src/test/resources/javaconfig/WEB-INF/web.xml
create mode 100644 resteasy-spring/src/test/resources/javaconfig/index.html
diff --git a/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/ServerConfiguration.java b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/ServerConfiguration.java
index b99a744..7627176 100644
--- a/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/ServerConfiguration.java
+++ b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/ServerConfiguration.java
@@ -1,6 +1,7 @@
package org.jboss.resteasy.spring.beanprocessor;
import org.jboss.resteasy.plugins.spring.EmbeddedContainerBean;
+
import org.jboss.resteasy.plugins.spring.SpringBeanProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigApplication.java b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigApplication.java
new file mode 100644
index 0000000..86bce72
--- /dev/null
+++ b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigApplication.java
@@ -0,0 +1,8 @@
+package org.jboss.resteasy.spring.test.javaconfig;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("rest")
+public class JavaConfigApplication extends Application {
+}
diff --git a/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigResource.java b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigResource.java
new file mode 100644
index 0000000..10dde17
--- /dev/null
+++ b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigResource.java
@@ -0,0 +1,33 @@
+package org.jboss.resteasy.spring.test.javaconfig;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * This class provides a web-based facade for an injected service.
+ */
+@Path("")
+public class JavaConfigResource {
+ JavaConfigService service;
+ @Autowired
+ public void setService(JavaConfigService service) {
+ System.out.println("*** service injected=" + service);
+ this.service = service;
+ }
+
+ public JavaConfigResource() {
+ System.out.println("*** resource created:" + super.toString());
+ }
+
+
+ @GET
+ @Path("invoke")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String invoke() {
+ return service.invoke();
+ }
+}
diff --git a/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigService.java b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigService.java
new file mode 100644
index 0000000..d18f60c
--- /dev/null
+++ b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigService.java
@@ -0,0 +1,10 @@
+package org.jboss.resteasy.spring.test.javaconfig;
+
+/**
+ * This POJO service bean will get injected into the resource.
+ */
+public class JavaConfigService {
+ public String invoke() {
+ return "hello";
+ }
+}
diff --git a/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigTest.java b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigTest.java
new file mode 100644
index 0000000..301767d
--- /dev/null
+++ b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/JavaConfigTest.java
@@ -0,0 +1,45 @@
+package org.jboss.resteasy.spring.test.javaconfig;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+
+import org.jboss.resteasy.client.ClientRequest;
+import org.jboss.resteasy.client.ClientResponse;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.webapp.WebAppContext;
+
+import com.meterware.servletunit.ServletRunner;
+
+/**
+ * This test will verify that the resource invoked by RESTEasy has been
+ * initialized by spring when defined using spring's JavaConfig.
+ */
+public class JavaConfigTest {
+ private static final String CONTEXT_PATH = "/";
+ private static final String BASE_URL = "http://localhost:9092";
+ private static final String PATH = "/rest/invoke";
+
+ @BeforeClass
+ public static void before() throws Exception {
+ Server server = new Server(9092);
+ WebAppContext context = new WebAppContext();
+ context.setResourceBase("src/test/resources/javaconfig");
+ context.setContextPath(CONTEXT_PATH);
+ context.setParentLoaderPriority(true);
+ server.setHandler(context);
+ server.start();
+ }
+
+ @Test
+ public void test() throws Exception {
+ ClientRequest request = new ClientRequest(BASE_URL + CONTEXT_PATH + PATH);
+ @SuppressWarnings("unchecked")
+ ClientResponse<String> response = request.get();
+ assertEquals("unexpected response code", 200, response.getResponseStatus().getStatusCode());
+ assertEquals("unexpected response msg", "hello", response.getEntity(String.class));
+ }
+}
diff --git a/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/TestConfig.java b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/TestConfig.java
new file mode 100644
index 0000000..4ddb7b8
--- /dev/null
+++ b/resteasy-spring/src/test/java/org/jboss/resteasy/spring/test/javaconfig/TestConfig.java
@@ -0,0 +1,19 @@
+package org.jboss.resteasy.spring.test.javaconfig;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * This java class defines the beans for the application.
+ */
+@Configuration
+public class TestConfig {
+ @Bean
+ public JavaConfigService service() {
+ return new JavaConfigService();
+ }
+ @Bean
+ public JavaConfigResource resource() {
+ return new JavaConfigResource();
+ }
+}
diff --git a/resteasy-spring/src/test/resources/javaconfig/WEB-INF/web.xml b/resteasy-spring/src/test/resources/javaconfig/WEB-INF/web.xml
new file mode 100644
index 0000000..f528142
--- /dev/null
+++ b/resteasy-spring/src/test/resources/javaconfig/WEB-INF/web.xml
@@ -0,0 +1,49 @@
+<!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>
+ <display-name>Spring JavaConfig-Powered Webapp Test</display-name>
+
+ <context-param>
+ <param-name>contextClass</param-name>
+ <param-value>
+ org.springframework.web.context.support.AnnotationConfigWebApplicationContext
+ </param-value>
+ </context-param>
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>org.jboss.resteasy.spring.test.javaconfig.TestConfig</param-value>
+ </context-param>
+ <context-param>
+ <param-name>resteasy.resources</param-name>
+ <param-value>org.jboss.resteasy.spring.test.javaconfig.JavaConfigResource</param-value>
+ </context-param>
+ <context-param>
+ <param-name>resteasy.servlet.mapping.prefix</param-name>
+ <param-value>/rest</param-value>
+ </context-param>
+
+ <listener>
+ <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
+ </listener>
+ <listener>
+ <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
+ </listener>
+
+ <servlet>
+ <servlet-name>Resteasy</servlet-name>
+ <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.jboss.resteasy.spring.test.javaconfig.JavaConfigApplication</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Resteasy</servlet-name>
+ <url-pattern>/rest/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>
+
diff --git a/resteasy-spring/src/test/resources/javaconfig/index.html b/resteasy-spring/src/test/resources/javaconfig/index.html
new file mode 100644
index 0000000..893d667
--- /dev/null
+++ b/resteasy-spring/src/test/resources/javaconfig/index.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>JavaConfig Test</title>
+ </head>
+<body>
+ <a href="/rest/invoke">Say Hello</a>
+</body>
+</html>
\ No newline at end of file
--
1.7.0.4
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Resteasy-users mailing list
Resteasy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/resteasy-users