|
From: Steven D. <ste...@gm...> - 2005-01-12 12:48:33
|
I've created a proof-of-concept implementation that allows intra-VM
method invocations.
I will probably release this code in a seperate jar but for now I
would like your feedback. What's missing from is the proxy factory for
clients and the exporter for the host.
This interface needs to be implemented by the exporter:
/**
* This interface needs to be implemented by exporter classes that
want to participate in intra-VM method
* invocation in the same thread as the caller of the invoked method.
This allows
* for an EJB-style integration pattern by calling objects that live
in the same VM but
* are managed by a separate container. The typical use case would be
a caller that lives in a
* web application (WAR) and calls a service object that lives in the
same VM but inside another
* web application.
*
* @author Steven Devijver
* @since 12-01-2005
*/
public interface InvocationHandler {
/**
* The interface of the service that is called. This interface is shipped
* by the application that hosts the service to other applications that want
* to call the service as a client. The interface class functions a an end
* point marked.
*
* @return the service interface
*/
public Class getServiceInterface();
/**
* This method is called by an invocation mediator to pass method invocations.
*
* @param invocation the method invocation
* @return the result of the method invocation
*/
public Object handleInvocation(Object invocation);
}
This is the mediator that passes method invocations to
InvocationHandler interfaces:
/**
* <p>This class offers a number of static methods to register and
* unregister InvocationHandler instances and pass method
* invocations to these instance based on end point interfaces.
*
* <p>In a servlet container setup where applications each living in a
* separate web application (WAR) environment this class needs to be loaded
* by the class loader that is shared by the web applications. The best location
* to put the jar file would be in the lib directory of the servlet engine.
*
* @author Steven Devijver
* @since 12-01-2005
*/
public class IntraVMInvocationMediator {
private static Map invocationHandlers = new Hashtable();
private IntraVMInvocationMediator() {
super();
}
/**
* Register a InvocationHandler instance with the mediator.
*
* @param invocationHandler the InvocationHandler instance
*/
public static void register(InvocationHandler invocationHandler) {
invocationHandlers.put(invocationHandler.getServiceInterface(), new
WeakReference(invocationHandler));
}
/**
* Unregister a InvocationHandler instance with the mediator.
*
* @param invocationHandler the InvocationHandler instance
*/
public static void unregister(InvocationHandler invocationHandler) {
invocationHandlers.remove(invocationHandler.getServiceInterface());
}
/**
* Pass a method invocation to a InvocationHandler instance based on the
* name of the service interface end point.
*
* @param serviceInterface the service interface end point
* @param invocation the method invocation
* @return the result of the method invocation
*/
public static Object invoke(Class serviceInterface, Object invocation) {
Map tmpMap = new HashMap(invocationHandlers);
for (Iterator iter = tmpMap.keySet().iterator(); iter.hasNext();) {
Class tmpClass = (Class)iter.next();
if (tmpClass.getName().equals(serviceInterface.getName())) {
WeakReference weakReference = (WeakReference)tmpMap.get(tmpClass);
InvocationHandler invocationHandler =
(InvocationHandler)weakReference.get();
if (invocationHandler != null) {
return invocationHandler.handleInvocation(invocation);
} else {
throw new RuntimeException("End point with interface [" +
serviceInterface.getName() + "] is not available!");
}
}
}
throw new RuntimeException("End point with interface [" +
serviceInterface.getName() + "] is not available!");
}
}
Steven
---------- Forwarded message ----------
From: Steven Devijver <ste...@gm...>
Date: Tue, 11 Jan 2005 13:32:50 +0100
Subject: application integration: intra-VM remoting
To: spr...@li...
Hi,
Consider an organization that has a number of applications each using
Spring. Each application is deployed as a separate war in the same
servlet container.
An application can expose specific services which allow integration
with other applications. Messaging is one solution for integration but
if you can use global transactions direct method calls in the same
thread is also a suitable integration pattern.
I don't want to re-configure the service beans belonging to one
application plus all its dependencies in each application that wants
to call said application. Instead I want to do a call through a client
library EJB style. Using Spring each application could provide the
persistent classes, interfaces of exposed services and a Spring config
file with a client setup to access these services. The service than
would live in one place: the servlet context of the application it
belongs to.
But I don't want to use the remoting strategies currently included
with Spring: HTTP invoker, Hessian, Burlap, RMI. For a number of
reasons this is not suitable:
- communication overhead in creating connections and serialization
while in the same VM.
- calls do not happen in the same thread -> no global transactions.
So all I can think of is to do remoting through an intra-VM mechanism.
I haven't got a clue on how to set up such a mechanism but I know it's
a typical use case for EJB applications (local home interfaces).
Steven
|