Hi all
I have a JAX-RS application running on Websphere Application Server 9.0.5 (Java 1.8). I would like to make use of spring for the backing business classes and hence was attempting to inject Spring (Core – version 5.3.27) beans into the JAX-RS application
I understand that theIBM JAX-RS implementation relies on the com.ibm.websphere.jaxrs.server.IBMRestServlet for its initialization. Following post at http://www.javavillage.in/spring-ioc-on-servlets.php , I tried creating a custom servlet extending the IBMRestServlet and adding Spring autowiring to its init method
package org.my.example;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import com.ibm.websphere.jaxrs.server.IBMRestServlet;
@Configurable
public class MyHttpServlet extends IBMRestServlet {
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
}
This required, the IBM Websphere jars ( From "Websphere installation folder/Dev") to be added to my POM along with spring-web, aspectjweaver, spring-aspects , spring-context-support, spring-context etc as mentioned in link
<dependency>
<groupId>com.ibm.websphere</groupId>
<artifactId>j2ee</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>C:/IBM/WebSphere/AppServer/dev/JavaEE/j2ee.jar</systemPath>
</dependency>
<dependency>
<groupId>com.ibm.websphere.appserver.api</groupId>
<artifactId>com.ibm.websphere.appserver.api.jaxrs</artifactId>
<version>1.0.80</version>
</dependency>
<dependency>
<groupId>org.apache.wink</groupId>
<artifactId>wink-server</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.ibm.websphere.appserver</groupId>
<artifactId>was_public</artifactId>
<version>9.0.0</version>
</dependency>
Following was added to web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>JAXRSConfiguration</servlet-name>
<servlet-class> org.my.example.MyHttpServlet </servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value> org.my.example.RestConfig </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
Note: org.my.example.RestConfig is my class that extends javax.ws.rs.core.Application
Unfortunately the build fails with following error which I am unable to resolve with any dependencies
java: cannot access com.ibm.ws.ras.instrument.annotation.InjectedFFDC
class file for com.ibm.ws.ras.instrument.annotation.InjectedFFDC not found
As an alternate approach, I tried injecting spring to Rest Resource
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
@Path("/mypath")
public class MyResource {
@Autowired
TestClass testClass;
private static final Logger LOGGER = LoggerFactory.getLogger(MyResource.class);
@POST
@Path("/subpath")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getMyResourceList(MyRequest request) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
TestClass tClass = applicationContext.getBean(TestClass.class);
if(tClass!=null){
LOGGER.debug("TestClass not null");
}
LOGGER.debug("tClass-------->-"+tClass.testMethod());
LOGGER.debug("testClass------>"+testClass.testMethod());
}
The Web.xml was modified as below
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
With servlet still pointing to IBMRestServlet as in original JAX-RS application
<servlet>
<servlet-name>JAXRSConfiguration</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value> org.my.example.RestConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
My Bean looks as follows
@Component
public class TestService {
public String testMethod(){
return "spring class";
}
}
Here I am successfully able to get the bean instance but since the Application context is created per resource, I do not think it's a good way.
Request your help and suggestions
Thanks in Advance
------------------------------
Sibi Vaithara
------------------------------