Tuesday, February 22, 2011

Linux Port forward for debug remote application

Sometime, we need to debug production server code.

Here is approach of doing this:
1) start remote server with Debug flag, ex port 8000
2) in window local host cygwin: ssh -L 8787:localhost:8000 remoteuser@remote.myserver.com
3) start eclipse with port 8787.


ps.
-Xdebug
-Xnoagent
-Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787
or:
SET args=%args% -Xdebug -Xnoagent -J-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n

Monday, February 21, 2011

Binary Web Service - Hessian

Currently, most web services are XML-based due to the advantage of XML self-describing and well support. However, the bandwidth and performance may be the issues for XML based web service.

Binary Web Service, by design, attempts to solve the above issues.
Hessian (http://hessian.caucho.com/) is one of binary web service implementation. We used it and it is proved to be a good approach. Following is the simple code of showing how to use Hessian.


First we create interface with two methods, hello and hiClient
public interface Basic {
public String hello();
public MyOutputResponse hiClient(MyInputRequest input);
}


Server Side:
1. Create implementation of that interface.
public class BasicService implements Basic {
private String _greeting = "My Hello world";

public void setGreeting(String greeting) {
_greeting = greeting;
}

public String hello() {
return _greeting;
}

public MyOutputResponse hiClient(MyInputRequest input) {
System.out.println(" from client: " + input.toString());
MyOutputResponse response = new MyOutputResponse();
response.setMsg("HI there from " + input.getFirstName());
return response;
}
}

2. Standard web.xml for Hessian service
<!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>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<param-name>home-class</param-name>
<param-value>example.service.BasicService</param-value>
</init-param>
<init-param>
<param-name>home-api</param-name>
<param-value>example.interfaces.Basic</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Where home-api refers defined interface and home-class is implementation of the interfaces.

Client Side:
public class BasicClient {
public static void main(String []args)
throws Exception
{
String url = "http://localhost/hessian_webapp/hello";

HessianProxyFactory factory = new HessianProxyFactory();
Basic basic = (Basic) factory.create(Basic.class, url);

//test first API hello
System.out.println("Hello from server: " + basic.hello());

//test second API hiClient
MyInputRequest input = new MyInputRequest();
input.setFirstName("Michael");
input.setLastName("W");
MyOutputResponse response = basic.hiClient(input);

System.out.println("hiClient from server: " + response.toString());
}
}

The url of http://localhost/hessian_webapp/hello is the servlet for the service.

HessianProxyFactory factory = new HessianProxyFactory();
Basic basic = (Basic) factory.create(Basic.class, url);

Get reference of the interface

Build/Deploy
I used maven to build Hessian web service and deployed to jboss.
Here is pom file:


<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>example</groupId>
<artifactId>hessian_webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>hessian_webapp Maven Webapp</name>
<url>http://maven.apache.org</url>
<build>
<finalName>hessian_webapp</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>example.client.BasicClient</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>


</profiles>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>


<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>3.1.5</version>
</dependency>
</dependencies>

</project>






Build/Deploy
1. build: mvn clean package
2. deploy: copy target\hessian_webapp.war to your web server
3. start server.
4. test service with following URL: http://localhost/hessian_webapp/hello
You will get "Hessian Requires POST"
5. Run client BasicClient
In command line:
mvn -Pclient

In Eclipse:
Right click BasicClient, and Run As Java Application.



Source code: click here to download source code.