A Technology Blog About Code Development, Architecture, Operating System, Hardware, Tips and Tutorials for Developers.

Showing posts with label JBOSS. Show all posts
Showing posts with label JBOSS. Show all posts

Thursday, December 13, 2012

Spring and RESTEasy

9:09:00 PM Posted by Satish , , , , , , , , , No comments
This tutorial I am going to demonstrate how to integrate Jboss RESTEasy and Spring 3 to create a RESTFul web service. Using this I am going to show how use spring context to get the service bean in web service class.
I am going to use the following tools and technologies.
  • Jersey 2.2.1.GA
  • Spring 3.0.5.RELEASE
  • JDK 1.7
  • Tomcat 7.0
  • Maven
  • Eclipse 
I am going to take you to the following areas in this tutorial.
  • Service Layer Interface
  • Service Layer Class
  • Web Service Class
  • Spring Bean Configuration
  • Configuration for Spring and RESTEasy
  • Application Deployment
  • Testing
Before start coding let's create a dynamic web project using the following maven command. 

1
mvn archetype:generate -DgroupId=com.techiekernel.rest -DartifactId=Spring-RESTEasy -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

After executing, the project will be get created with pom.xml file. As I am using JDK 7 and annotations, I have to specify the updated maven plugin. After giving the RESTEasy and Spring dependency, the pom.xml looks as following.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<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.techiekernel.rest</groupId>
  <artifactId>Spring-RESTEasy</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>JAXRS-Jersey Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <repositories>
    <repository>
      <id>JBoss repository</id>
      <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
    </repository>
  </repositories>
 
  <dependencies>
 
    <!-- JBoss RESTEasy -->
    <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-jaxrs</artifactId>
      <version>2.2.1.GA</version>
    </dependency>
 
    <!-- Spring 3 dependencies -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>3.0.5.RELEASE</version>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.5.RELEASE</version>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>3.0.5.RELEASE</version>
    </dependency>
 
    <!-- need for solution 1, if your container don't have this -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.4</version>
    </dependency>
    </dependencies>
    <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1.1</version>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
    <finalName>Spring-RESTEasy</finalName>
  </build>
</project>

Service Layer Interface:

1
2
3
4
5
package com.techiekernel.service;

public interface FooBarService {
  public String getMessage(String msg);
}

Service Layer Class:

1
2
3
4
5
6
7
8
package com.techiekernel.service;

public class FooBarServiceImpl implements FooBarService{
  public String getMessage(String msg) {
    String output = "FooBar say : " + msg;
    return output;
  }
}

Web Service Class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.techiekernel.rest;

import javax.servlet.ServletContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.techiekernel.service.FooBarService;

@Component
@Path("/foobar")
public class FooBarWS {
  FooBarService fooBarService;
 
  @GET
  @Path("/{param}")
  public Response getMessage(@PathParam("param") String msg, @Context ServletContext servletContext) {
    //get Spring application context
        ApplicationContext ctx = 
                         WebApplicationContextUtils.getWebApplicationContext(servletContext);
        fooBarService= ctx.getBean("FooBar",FooBarService.class);
    return Response.status(200).entity(fooBarService.getMessage(msg)).build();
  }
}

Using the spring context to get the bean in stead of IOC does not look good to me. I suggest you to check this post for better integration. I followed the example, but that did not work for me.. So I end up doing this mess. But I strongly suggest to give a try to this post.

Spring Bean Configuration:

Now it is time to create the configuration for spring beans in applicationContext.xml. It is very much required to place the following configuration in classpath, so that container will read from the deployment descriptor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<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:component-scan base-package="com.techiekernel.rest" />

  <bean id="FooBar" class="com.techiekernel.service.FooBarServiceImpl" />

</beans>

Configuration for Spring and RESTEasy:

The integration is going to be in web.xml. Register Spring “ContextLoaderListener” listener class and specify the RESTEasy servlet “org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher“ as front controller for web services.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<web-app id="WebApp_ID" 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">
  <display-name>Spring RESTEasy</display-name>

  <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>com.techiekernel.rest.FooBarWS</param-value>
  </context-param>
 
  <listener>
    <listener-class>
      org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
                </listener-class>
  </listener>
 
  <listener>
    <listener-class>
                        org.springframework.web.context.ContextLoaderListener
                </listener-class>
  </listener>
 
 <!-- this need same with resteasy servlet url-pattern -->
  <context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/ws</param-value>
  </context-param>
  <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>/ws/*</url-pattern>
  </servlet-mapping>
</web-app>

Application Deployment:

Now every thing is ready and time to build for creating a war file.

1
mvn clean install;

n successful completion of the above command a war file will be get created in target folder. Copy the war file to webapp folder of your tomcat and start the tomcat.

Testing:

Once tomcat is started use the following url to access the web service.

1
http://localhost:8080/Spring-RESTEasy/ws/foobar/techiekernel

Once you hit the url in the browser, you are going to get the following output.


1
FooBar say : techiekernel


Source Code:

You can pull the code from GitHub.

Sunday, December 9, 2012

JAX-RS With Jboss RESTEasy

5:10:00 PM Posted by Satish , , , , , , , No comments
RESTEasy, JBoss project, implementation of the JAX-RS specification. In this tutorial, I will show you how to develop a simple RESTful web service with RESTEasy framework. 


I am going to use the following tools and technologies.
  • RESTEasy 2.2.1.GA
  • JDK 1.7
  • Tomcat 7.0
  • Maven
  • Eclipse 
I am going to take you to the following areas in this tutorial.
  • Service Class and Mapping Configuration
  • Front Controller And Listener Configuration
  • Application Deployment
  • Testing
Before start coding let's create a dynamic web project using the following maven command. 

1
mvn archetype:generate -DgroupId=com.techiekernel.rest -DartifactId=JAXRS-RESTEasy -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

After executing, the project will be get created with pom.xml file. As I am using JDK 7 and annotations, I have to specify the updated maven plugin. After giving the RESTEasy dependency, the pom.xml looks as following.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<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.techiekernel.rest</groupId>
  <artifactId>JAXRS-RESTEasy</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>JAXRS-Jersey Maven Webapp</name>
  <url>http://maven.apache.org</url>

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

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-jaxrs</artifactId>
      <version>2.2.1.GA</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1.1</version>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
    <finalName>JAXRS-RESTEasy</finalName>
  </build>
</project>

Service Class and Mapping Configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.techiekernel.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

@Path("/foobar")
public class FooBarService {
  @GET
  @Path("/{param}")
  public Response getMsg(@PathParam("param") String msg) {
 
    String output = "Jersey say : " + msg;
 
    return Response.status(200).entity(output).build();
 
  }
}

Front Controller and Listener Configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<web-app id="WebApp_ID" 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">
  <display-name>JAXRS-RESTEasy</display-name>
  <!-- Auto scan REST service -->
  <context-param>
    <param-name>resteasy.scan</param-name>
    <param-value>true</param-value>
  </context-param>

  <!-- this need same with resteasy servlet url-pattern -->
  <context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/ws</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>/ws/*</url-pattern>
  </servlet-mapping>
</web-app>

You need to set the “resteasy.servlet.mapping.prefix” if your servlet-mapping for the resteasy servlet has a url-pattern other than “/*“.
In above example, the resteasy servlet url-pattern is “/ws/*“, so you have to set the “resteasy.servlet.mapping.prefix” to “/ws” as well, otherwise, you will hit resource not found error message.
Remember to set “resteasy.scan” to true, so that RESTEasy will find and register your REST service automatically.

Application Deployment:

Now every thing is ready and time to build for creating a war file.

1
mvn clean install;

On successful completion of the above command a war file will be get created in target folder. Copy the war file to webapp folder of your tomcat and start the tomcat.

Testing:

Once tomcat is started use the following url to access the web service.

1
http://localhost:8080/JAXRS-RESTEasy/ws/foobar/foobar

Output:

Once you hit the url in the browser, you are going to get the following output.

1
FooBar say : foobar

Source Code:

You can pull the code from GitHub.

Sunday, December 19, 2010

APACHE SETUP FOR JBOSS

2:36:00 PM Posted by Satish , , , , No comments
1. Download Apache HTTP 2.2 from here(http://olex.openlogic.com/package_versions/download/9478?package_version_id=5577&path=openlogic%2Fapache%2F2.2.17%2Fopenlogic-apache-2.2.17-windows-ins-no-ssl-1.zip)


2. Unzip the file and double click on the installation file. Next follow the screen instructions to install.

3. After installation click the test configuration to test if Apache is working or not.

4. Now start the apache by clicking start from Apache sub menu.

5. Request for http://localhost/ to check the status.

6. Now time to confirure the proxy set up for Jboss. To do so we are going to use the the mod jk module in apache http.

7. Download themod_jk-1.2.31-httpd-2.2.3.s from here(http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.31/mod_jk-1.2.31-httpd-2.2.3.so).

8. Rename the file to mod_jk.so and put to the "$apache_home/modules/" folder.

9. Now open the "$apache_home/conf/httpd.conf" and add the following lines at the end.

<IfModule !mod_jk.c>
  LoadModule jk_module modules/mod_jk.so
</IfModule>

#Include mod_jk configuration file
Include "C:/Program Files/Apache Software Foundation/Apache2.2/conf/mod-jk.conf"

Note: change the path acording to your environment.

10. Create a file "$apache_home/conf/mod-jk.conf" and add the following content to that.

# Load mod_jk module
# Specify the filename of the mod_jk lib
#LoadModule jk_module modules/mod_jk.so

# Where to find workers.properties
#JkWorkersFile conf/workers.properties
JkWorkersFile conf/workers.properties


# Where to put jk logs
#JkLogFile logs/mod_jk.log
JkLogFile logs/mod_jk.log

# Set the jk log level [debug/error/info]
JkLogLevel info

# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"

# JkOptions indicates to send SSK KEY SIZE
# Notes:
# 1) Changed from +ForwardURICompat.
# 2) For mod_rewrite compatibility, use +ForwardURIProxy (default since 1.2.24)
# See http://tomcat.apache.org/security-jk.html
JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories

# JkRequestLogFormat
JkRequestLogFormat "%w %V %T"

# Mount your applications
JkMount /__application__/* node1

# Let Apache serve the images
#JkUnMount /__application__/images/* node1


# You can use external file for mount points.
# It will be checked for updates each 60 seconds.
# The format of the file is: /url=worker
# /examples/*=ajp13
JkMountFile  conf/uriworkermap.properties

# Add shared memory.
# This directive is present with 1.2.10 and
# later versions of mod_jk, and is needed for
# for load balancing to work properly
# Note: Replaced JkShmFile logs/jk.shm due to SELinux issues. Refer to
# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=225452
JkShmFile run/jk.shm

# Add jkstatus for managing runtime data
<Location /jkstatus>
JkMount status
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>

11. Now create "$apache_home/conf/workers.property" and add the following lines to that.

# Define list of workers that will be used
# For mapping requests
worker.list=node1,status


# Define Node1
worker.node1.port=8009
worker.node1.host=10.5.1.26
worker.node1.type=ajp13
#ping_mode as of mod_jk
worker.node1.ping_mode=A
#worker.node1.socket_timeout=10
        
# Status worker for managing load balancer
worker.status.type=status
#worker.localhost.host=10.5.1.26

Note: Change the host IP according to your IP. This configuration has been done for only one node. So there is no load balancer. You can add more than two nodes and a load balancer to manage. You can also enable sticky session if Jboss clustering and session replication is not enabled. 

12. Now create "$apache_home/conf/uriworkermap.properties" and add the following lines to that.

# Mount the Servlet context to the ajp13 worker
/jmx-console=node1
/jmx-console/*=node1
/web-console=node1
/web-console/*=node1
/test=node1
/test/*=node1

13. Now Jboss has to be configured to work with Apache.

A) Open "$jboss_Home/server//deploy/jboss.web-deployer/server.xml"

search for the following line and specify jvmRoot attribute to node1 as bellow.
Engine name = ”jboss.web” default host = “hostname” jvmRoute = “node1”

B)  Open "$jboss_Home/server/<instance_name>/deploy/jboss.web-deployer/meta-INF/jboss-service.xml"

search for "useJK" and make the value to "true" as bellow.
<attributename = “UseJK” > true</attribute>

14. Now restart the both web and app server. To test access test from web server DNS ie http://localhost/test.