Service Oriented Java Business Integration Proxy

Exclusive offer: get 50% off this eBook here
Service Oriented Java Business Integration

Service Oriented Java Business Integration — Save 50%

Enterprise Service Bus integration solutions for Java developers with this SOA book and eBook

$29.99    $15.00
by Binildas A. Christudas | April 2010 | .NET BPEL Microsoft SOA Web Services

We will cover the following in this article by Binildas A. Christudas, author of Service Oriented Java Business Integration:

  • Proxy design pattern in general
  • Proxy support in Java SDK with examples
  • ServiceMix JBI Proxy
  • A few samples of defining and exposing proxies to services in the JBI bus

Proxy—A Primer

Wikipedia defines Proxy as:

Proxy may refer to something which acts on behalf of something else.

In the software a proxy is a substitute for a target instance and is a general pattern which appears in many other patterns in different variants.

Proxy Design Pattern

A proxy is a surrogate class for the target object. If a method call has to be invoked in the target object, it happens indirectly through the proxy object. The feature which makes proxy ideal for many situations is that the client or the caller is not aware that it is dealing with the proxy object. The proxy class is shown in the following figure:

Service Oriented Java Business Integration

In the above figure, when a client invokes a method target towards the Target service, the proxy intercepts the call in between. The proxy also expose a similar interface to the target, hence the client is unaware of the dealing with the proxy. Thus the proxy method is invoked. The proxy then delegates the call to the actual target since it cannot provide the actual functionality. When doing so, the proxy can provide call management towards the actual method. The entire dynamics is shown in the following figure:

Service Oriented Java Business Integration

A proxy is usually implemented by using a common, shared interface or super class. Both the proxy and the target share this common interface. Then, the proxy delegates the calls to the target class.

JDK Proxy Class

JDK provides both the class Proxy and the interface InvocationHandler in the java.lang.reflect package, since version 1.3. Using JDK Proxy classes, you can create your own classes implementing multiple interfaces of your choice, at run time.

Proxy is the super class for any dynamic proxy instances you create at run time. Moreover, the Proxy class also accommodates a host of static methods which will help you to create your proxy instances. getProxyClass and newProxyInstance are two such utility methods.

The Proxy API is listed in the following in brevity:

package java.lang.reflect;
public class Proxy implements java.io.Serializable
{
protected InvocationHandler h;
protected Proxy(InvocationHandler h);
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException;
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException;
public static boolean isProxyClass(Class<?> cl);
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h)
throws IllegalArgumentException
}


In the above code, you can invoke the Proxy.getProxyClass with a class loader and an array of interfaces for which you need to proxy, to get a Class instance for the proxy. Proxy objects have one constructor, to which you pass an InvocationHandler object associated with that proxy. When you invoke a method on the proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler. Let us also look at the InvocationHandler API reproduced as follows:

package java.lang.reflect;
public interface InvocationHandler
{
Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}

We need to implement this interface and provide code for the invoke method. Once you get a Class instance for the proxy by invoking the Proxy.getProxyClass with a class loader and an array of interfaces for which you need to proxy to. Now, you can get a Constructor object for this proxy from the Class instance. On the constructor you can use newInstance (passing in an invocation handler instance) to create the proxy instance. The created instance should be implementing all the interfaces that were passed to getProxyClass. The steps are shown in the following code:

InvocationHandler handler = new SomeInvocationHandler(...);
Class proxyClazz = Proxy.getProxyClass(Blah.class.getClassLoader(),
new Class[] {Blah.class});
Blah blah = (Blah) proxyClazz.getConstructor(new Class[] {
InvocationHandler.class }).newInstance(new Object[]
{handler});

There is also a shortcut to get a proxy object. You can invoke Proxy.newProxyInstance, which takes a class loader, an array of interface classes, and an invocation handler instance.

InvocationHandler handler = new SomeInvocationHandler(...);
Blah blah = (Blah) Proxy.newProxyInstance(Blah.class.
getClassLoader(),new Class[] {Blah.class},
handler);

Now you can invoke methods on the proxy object during which these method invocations are turned into calls on to the invocation handler's invoke method is shown here:

blah.interfaceMethod();

Sample JDK Proxy Class

We will now write some simple code to demonstrate how you can write your own proxies at run time, for your interface classes.

As a first step, if you haven't done it before, edit examples.PROPERTIES, and change the paths there to match your development environment.

We will now look at the source code that can be found in the folder ch13\JdkProxy\src.

The files are explained here:

ch13\JdkProxy\src\SimpleIntf.java
public interface SimpleIntf
{
public void print();
}

SimpleIntf is a simple interface with a single method print. print does not accept any parameters and also does not return any value. Our aim is that when we invoke methods on the proxy object for SimpleIntf, the method invocation should be turned into calls to an invocation handler's invoke method. Let us now define an invocation handler in the following code:

ch13\JdkProxy\src\SimpleInvocationHandler.java

import java.lang.reflect.InvocationHandler;
import java.io.Serializable;
import java.lang.reflect.Method;
public class SimpleInvocationHandler implements InvocationHandler,
Serializable
{
public SimpleInvocationHandler(){}
public Object invoke(final Object obj, Method method,
Object[] args) throws Throwable
{
if (method.getName().equals("print") && (args == null
|| args.length == 0))
{
System.out.println("SimpleInvocationHandler.invoked");
}
else
{
throw new IllegalArgumentException("Interface method does
not support param(s) : " + args);
}
return null;
}
}

Since SimpleIntf.print() does not accept any parameters and also does not return any value, in the invoke method of SimpleInvocationHandler, we double check the intention behind the actual invoker. In other words, we check that no parameters are passed and we return null only.

Now, we have all the necessary classes to implement a proxy for SimpleIntf interface. Let us now execute it by writing a Test class.

ch13\JdkProxy\src\Test.java

import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
public class Test
{
public static void main(String[] args)
{
InvocationHandler handler = new SimpleInvocationHandler();
SimpleIntf simpleIntf = (SimpleIntf)Proxy.newProxyInstance
(SimpleIntf.class.getClassLoader(),new Class[] { SimpleIntf.
class }, handler);
simpleIntf.print();
}
}



The wiring of the above described interfaces and classes are better represented in the UML class diagram in the following figure:

Service Oriented Java Business Integration

The above figure shows the relationship between various classes and interfaces in the sample. $Proxy0 class represents the actual proxy class generated on the fly and as you can deduce it from the class diagram. $Proxy0 is a type of our interface (SimpleIntf).

To build the sample, first change directory to ch13\JdkProxy and execute ant as shown here:

cd ch13\JdkProxy
ant

The command ant run will execute the Test class which will print out the following in the console:

Service Oriented Java Business Integration

ServiceMix JBI Proxy

Java proxies for the JBI endpoints can be created in ServiceMix using JSR181 components. For this, the requirement is that the JBI endpoints should expose a WSDL.

A jsr181:endpoint takes a value for the serviceInterface attribute. The JBI container will be able to generate the WSDL out of this serviceInterface. Thus, if we have a jsr181:endpoint exposing service to the JBI bus, it is possible to provide a proxy for that service too.

The basic configuration for defining a JBI proxy is shown as follows:

<jsr181:proxy id="proxyBean"
container="#jbi"
interfaceName="test:HelloPortType"
type="test.Hello" />

Once a proxy is defined, the same can then be referenced from your client bean or from one of your components. The proxied JBI endpoint can then be invoked just like a normal POJO.

If you want to define a JBI proxy within a SU, you can follow the configuration given as follows:

<jsr181:endpoint annotations="none"
service="test:echoService"
serviceInterface="test.Echo">
<jsr181:pojo>
<bean class="test.EchoProxy">
<property name="echo">
<jsr181:proxy service="test:EchoService"
context="#context"
type="test.IService" />
</property>
</bean>
</jsr181:pojo>
</jsr181:endpoint>

Let us now look into a few examples to make the concept clearer.

JBI Proxy Sample Implementing Compatible Interface

First, we will create a JBI proxy implementing an interface compatible with the target service. Then, in place of the target service we will use the proxy instance, so that any calls intended for the target service will be first routed to the proxy. The proxy in turn will delegate the call to the target service. The structural relationship between various classes participating in the interaction is shown in the following figure:

Service Oriented Java Business Integration

Here, EchoProxyService is the class which we later expose in the JBI bus as the service. This class implements the IEcho interface. In order to demonstrate the proxy, EchoProxyService doesn't implement the service as such, instead depends on the JbiProxy derived out of another class TargetService. The TargetService contains the actual service code. As you can see, both the EchoProxyService and the TargetService implement the same interface.

Proxy Code Listing

The codebase for the sample is located in the folder ch13\JbiProxy\01_CompatibleInterface\01_JsrProxy\src.

This folder contains an interface IEcho and two other classes implementing the IEcho interface namely EchoProxyService and TargetService. These classes are explained here:

  • IEcho.java: The IEcho interface declares a single method echo which takes a String parameter and returns a String.
  • public interface IEcho
    {
    public String echo(String input);
    }
  • EchoProxyService.java: EchoProxyService is a convenient class which will act as mechanism for routing requests to the JBI proxy. Moreover, EchoProxyService implements the above interface IEcho.
  • public class EchoProxyService implements IEcho
    {
    private IEcho echo;
    public void setEcho(IEcho echo)
    {
    this.echo = echo;
    }
    public String echo(String input)
    {
    System.out.println("EchoProxyService.echo. this = " + this);
    return echo.echo(input);
    }
    }
  • TargetService.java: TargetService also implements the interface IEcho. TargetService is supposed to be our target service, and we will be generating a JBI proxy for the TargetService.
  • public class TargetService implements IEcho
    {
    public String echo(String input)
    {
    System.out.println("TargetService.echo : String. this = " +
    this);
    return input;
    }
    }
Service Oriented Java Business Integration Enterprise Service Bus integration solutions for Java developers with this SOA book and eBook
Published: March 2008
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

XBean-based JBI Proxy Binding

Using XBean, we will now configure the JBI proxy to be deployed onto the standard servicemix-jsr181 JBI component. The xbean.xml is as shown as follows:

<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:jsr181="http://servicemix.apache.org/jsr181/1.0"
xmlns:http="http://servicemix.apache.org/http/1.0"
xmlns:test="http://test">
<classpath>
<location>.</location>
</classpath>
<jsr181:endpoint annotations="none"
service="test:echoService"
serviceInterface="test.IEcho">
<jsr181:pojo>
<bean class="test.EchoProxyService">
<property name="echo">
<jsr181:proxy service="test:TargetService"
context="#context"
type="test.IEcho" />
</property>
</bean>
</jsr181:pojo>
</jsr181:endpoint>
<jsr181:endpoint annotations="none"
service="test:TargetService"
serviceInterface="test.IEcho">
<jsr181:pojo>
<bean class="test.TargetService" />
</jsr181:pojo>
</jsr181:endpoint>
</beans>

Here we first wire both EchoProxyService and TargetService as JSR181-compliant services onto the JBI bus. Next we define a JBI proxy for the TargetService. If we closely observe the proxy configuration, we can see that we are insisting that the proxy to implement the type test.IEcho. That makes sense and is not a surprise since the target service class, test:TargetService is also of type test.IEcho.

Deployment Configuration

For deployment, we will package the relevant artifacts for the JSR proxy binding into a standard SA. We will also have an HTTP bound SA so that we can use a simple HTTP client to test the setup. As the configurations are exactly the same as what we used in the previous example, they are not repeated here.

Deploying and Running the Sample

To build the entire codebase and deploy the sample, change directory to ch13\JbiProxy\01_CompatibleInterface which contains a top-level build.xml file. Execute ant as shown here:

cd ch13\JbiProxy\01_CompatibleInterface
ant

Now, bring up the ServiceMix container by executing the servicemix.xml file contained in the same folder.

cd ch13\JbiProxy\01_CompatibleInterface
%SERVICEMIX_HOME%/bin/servicemix servicemix.xml

The Client.html provided again in the same folder can be used to send messages to test the deployed service. Now clicking Send on the client will route the request message to the ServiceMix ESB. At the ServiceMix console, you can see that EchoProxyService.echo is invoked first, which will then delegate the call to TargetService.echo. This is shown in the following screenshot:

Service Oriented Java Business Integration

JBI Proxy Sample implementing In-Compatible interface

In the second sample on JBI Proxy, we will make a simple but significant change in the interfaces implemented. We will create a JBI proxy implementing an interface incompatible to the target service. Then, in place of the target service we will use the proxy instance. Then any calls intended to the target service will be first routed to the proxy and the proxy in turn will delegate the call to the target service. The structural relationship between various classes participating in the interaction is shown in the figure:

Service Oriented Java Business Integration

In the above figure, you might have noticed that even though we use two completely different types (IEcho and ITarget) as the interfaces, the methods declared in these two interfaces are the same in every respect. This is a hack we want to introduce intentionally. In other words our aim here is to invoke the method in TargetService. But, we want to do it through the proxy only. We want the proxy to be created implementing a different interface, IEcho. Hence, IEcho is different from the ITarget. This means if we go by the normal Java type compatibility rules, the proxy which we created here is "technically incompatible" with the target service. But a proxy is a proxy and hence it can proxy calls even to a different type. However, As we want to invoke the same method in the proxy too, we have purposefully kept the method name same in both the proxy interface and the target service interface.

Proxy Code Listing

The codebase for the sample is located in the folder ch13\JbiProxy\02_IncompatibleInterface\01_JsrProxy\src.

This folder contains the interface IEcho and the class EchoProxyService implementing the IEcho interface. Now, we have one more interface ITarget and another class TargetService implementing the ITarget interface.

These classes are explained here:

  • IEcho.java: In this sample also, the IEcho interface declares a single method echo which takes a String parameter and returns a String too.
  • public interface IEcho
    {
    public String echo(String input);
    }
  • EchoProxyService.java: Here also the EchoProxyService is a convenient class which will act as mechanism for routing requests to the JBI Proxy. Moreover, EchoProxyService implements the above interface IEcho.
  • public class EchoProxyService implements IEcho
    {
    private IEcho echo;
    public void setEcho(IEcho echo)
    {
    this.echo = echo;
    }
    public String echo(String input)
    {
    System.out.println("EchoProxyService.echo. this = " + this);
    return echo.echo(input);
    }
    }
  • ITarget.java: Here, we introduce a new interface ITarget, which is incompatible to the interface IEcho. But purposefully we have retained the method echo.
  • public interface ITarget
    {
    String echo(String input);
    }
  • TargetService.java: As per our discussion earlier, TargetService implements the new interface ITarget, not IEcho.

  • public class TargetService implements ITarget
    {
    public String echo(String input)
    {
    System.out.println("TargetService.echo : String. this = " +
    this);
    return input;
    }
    }

XBean-based JBI Proxy Binding

Using XBean, we will now configure the JBI proxy to be deployed onto the standard servicemix-jsr181 JBI component. The xbean.xml is as shown as follows:

<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:jsr181="http://servicemix.apache.org/jsr181/1.0"
xmlns:http="http://servicemix.apache.org/http/1.0"
xmlns:test="http://test">
<classpath>
<location>.</location>
</classpath>
<jsr181:endpoint annotations="none"
service="test:echoService"
serviceInterface="test.IEcho">
<jsr181:pojo>
<bean class="test.EchoProxyService">
<property name="echo">
<jsr181:proxy service="test:TargetService"
context="#context" type="test.IEcho" />
</property>
</bean>
</jsr181:pojo>
</jsr181:endpoint>
<jsr181:endpoint annotations="none"
service="test:TargetService"
serviceInterface="test.ITarget">
<jsr181:pojo>
<bean class="test.TargetService" />
</jsr181:pojo>
</jsr181:endpoint>
</beans>

Observe the proxy configuration again. We can see that this time we are insisting that the proxy implements the type test.IEcho, even though the interface type for the target service is test.ITarget. This is what a proxy is all about. In clear terms, the JBI here will generate a proxy for test.TargetService. So the proxy's exposed interface is, by default, compliant to test.ITarget. However, we want the proxy to be compliant to test.IEcho also, which is the interface the client initially targeted to.

Deployment Configuration

For deployment, we will package again all the relevant artifacts for the JSR proxy binding into a standard SA. We will also have an HTTP bound SA so that we can use a simple HTTP client to test the setup. As the configurations are exactly the same as what we used in previous example, they are not repeated here.

Deploying and Running the Sample

To build the entire codebase and deploy the sample, change directory to ch13\JbiProxy\02_IncompatibleInterface which contains a top-level build.xml file. Execute ant as shown here:

cd ch13\JbiProxy\02_IncompatibleInterface
ant

Now, bring up the ServiceMix container by executing the servicemix.xml file contained in the same folder.


cd ch13\JbiProxy\02_IncompatibleInterface
%SERVICEMIX_HOME%/bin/servicemix servicemix.xml

The Client.html file provided in the same folder can be used to send messages to test the deployed service. Now clicking Send on the client will route the request message to the ServiceMix ESB. At the ServiceMix console you can see that EchoProxyService.echo is invoked first which will then delegate the call to TargetService.echo. This is shown in the following screenshot:

Service Oriented Java Business Integration

Summary

Proxies are strong features in the Java language package, and similar functionality can be availed from within your JBI ESB using JBI proxies. Interception and re-routing are some of the features we can implement using proxies.


If you have read this article you may be interested to view :

Service Oriented Java Business Integration Enterprise Service Bus integration solutions for Java developers with this SOA book and eBook
Published: March 2008
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

About the Author :


Binildas A. Christudas

Binildas C. A. provides Technical Architecture consultancy for IT solutions. He has over 13 years of IT experience, mostly in Microsoft and Sun technologies. Distributed Computing and Service Oriented Integration are his main stream skills, with extensive hands-on experience in Java and C#.NET programming. Binil holds a BTech. degree in Mechanical Engineering from College of Engineering, Trivandrum (www.cet.ac.in) and an MBA in Systems Management, from Institute of Management, Kerala (www.imk.ac.in). A well-known and a highly sought-after thought leader, Binil has designed and built many highly scalable middle-tier and integration solutions for several top-notch clients including Fortune 500 companies. He has been previously employed by multiple IT consulting firms including IBS Software Services (www.ibsplc.com) and Tata Consultancy Services (www.tcs.com) and currently works for Infosys Technologies (www.infosys.com) as a Principal Architect where he heads the J2EE Architects group servicing Communications Service Provider clients.

Binil is a Sun Certified Programmer (SCJP), Developer (SCJD), Business Component Developer (SCBCD) and Enterprise Architect (SCEA), Microsoft Certified Professional (MCP) and Open Group (TOGAF8) Certified Enterprise Architecture Practitioner. He is also a Licensed Zapthink Architect (LZA) in SOA. Besides Technical Architecture Binil also practices Enterprise Architecture.

When not in software, Binil spends time with wife Sowmya & daughter Ann in ‘God's Own Country’, Kerala (www. en.wikipedia.org/wiki/Kerala). Binil does long distance running and is a national medalist in Power Lifting. You may contact Binil at biniljava@yahoo.co.in or binil_christudas@infosys.com.

Books From Packt


Microsoft Dynamics AX 2009 Programming: Getting Started
Microsoft Dynamics AX 2009 Programming: Getting Started

BPEL PM and OSB operational management with Oracle Enterprise Manager 10g Grid Control
BPEL PM and OSB operational management with Oracle Enterprise Manager 10g Grid Control

RESTful Java Web Services
RESTful Java Web Services

SOA Patterns with BizTalk Server 2009
SOA Patterns with BizTalk Server 2009

Oracle SOA Suite Developer's Guide
Oracle SOA Suite Developer's Guide

Oracle SOA Suite Developer's Guide
Oracle SOA Suite Developer's Guide

Oracle SOA Suite 11g R1 Developer's Guide
Oracle SOA Suite 11g R1 Developer's Guide

Amazon SimpleDB Developer Guide
Amazon SimpleDB Developer Guide


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
e
s
s
U
m
z
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software