180 likes | 258 Views
A Framework for Smart Proxies and Interceptors in RMI. Nuno Santos P. Marques, L. Silva CISUC, University of Coimbra, Portugal nsantos@dei.uc.pt. Outline. Motivation Design and Implementation Example: Integration of RMI with JAAS Performance Conclusion. Motivation Problem.
E N D
A Framework for Smart Proxies and Interceptors in RMI Nuno Santos P. Marques, L. Silva CISUC, University of Coimbra, Portugalnsantos@dei.uc.pt
Outline • Motivation • Design and Implementation • Example: Integration of RMI with JAAS • Performance • Conclusion
MotivationProblem • RMI makes it easy to build distributed applications • Hides the complexity of communication. • Programmers just need to program the application layer. • But sometimes it is necessary to customize other layers: • Service-specific code: QoS, Security, logging and accounting, client-side caching, fault tolerance • Should be orthogonal to the application code. • RMI makes it hard to customize other layers. • The only hook into the middleware are for sockets. • Other types of services must be implemented at the application layer. Dependence between service and application-specific code
MotivationConcepts • Solutions? • Use J2EE? • An application server supports separation between application and service-specific code. • Overkill for most applications! A more lightweight approach is preferable. • Other middleware systems (CORBA, .Net Remoting framework) have addressed this issue. • Smart Proxies • Interceptors
MotivationInterceptors • Developer defined objects invoked by the communication system in the path of the remote method invocation. • Intercept, process and forward the invocation. • Can be chained. • Independent of each other. • Ideal for adding stages of processing to a remote invocation.
MotivationSmart Proxies • A more capable stub. • Intercepts calls at the client side. • Processes them in a way defined by the developer. • May or may not forward them to the server. Our objective: implement smart proxies and interceptors on RMI!
Design and ImplementationHow to do it • The developer defines the smart proxy and interceptors, which are independent of the application level objects. • At bind time, it is necessary to: • Send the smart proxy and the client side interceptor to the client. • Place the interceptors on the invocation path of a remote call, both at the client and at the server.
Design and ImplementationTools • Java support for Code Mobility • When a client binds to a server, RMI sends a pre-generated stub to the client. • Other objects can also be sent during binding: smart proxy and interceptors. • Dynamic Proxy API • Allows the generation of proxies at runtime. • Used to change the invocation path.
Design and ImplementationPutting it all together • ServiceDynamicProxy is exported instead of remote object. • Sent by value at bind time. • Objects referenced by it (ClientProxy, the InvocationHandler) are sent to the client automatically. • ClientProxy references an optional interceptor and the ServerProxy. • ServerProxy is a remote object, so is passed by reference (only the stub). • Binding complete.
Design and ImplementationOther Issues - Exception handling • Application exceptions are sent to the client • Remote exception can be handled the following ways: • At the client, by a developer defined exception handler (usefull for implementing retries). • Sent to the client as a RemoteException. • RMI semantics • Sent to the client as a RuntimeException. • Remote semantic hidden from client. • Usefull for legacy applications
Design and ImplementationExample • Measuring the time a remote invocation takes Interceptor Server public class ClientTimerInterceptor implements ClientInterceptor { … // Measures the time it takes for the call public Object handleRemote(Dispatcher proxy, Method method, Object[] args) throws Throwable { long time = -System.currentTimeMillis(); Object result = proxy.dispatch(method, args); time += System.currentTimeMillis(); System.out.println("Client time taken: " + time); return result; } } public class Server { public static void main(String[] args) throws Exception { … ExecutionEngine engine = new ExecutionEngineImpl(); RMIProxyFactory proxyFactory = new RMIProxyFactory( engine, new Class[]{ExecutionEngine.class}); ClientTimerInterceptor clientInt = new ClientTimerInterceptor(); Remote proxy = (Remote) proxyFactory.getClientDynamicProxy( clientInt, null); Naming.rebind(args[0], proxy); … }
Authenticated RMI invocationsThe problem • JAAS (Java Authentication and Authorization Service) • Extension to the standard Java security model. (> JDK 1.3) • Introduces the notion of user. • Permissions granted based also on WHO is executing the code. • But... does not extend to RMI calls, user information is lost.
Authenticated RMI invocationsOur solution – Conceptual model • Clients must authenticate before using remote objects • A Login object is exported. Clients authenticate with it. • On sucessful authentication, a new proxy for the service is exported and a reference given to the client • One client, one proxy. Proxies know the credentials of their clients.
Authenticated RMI invocationsOur solution - Implementation • A server side interceptor is used as proxy. • knows the caller identity. • Uses it to invoke the service
Performance Legend SingleInt – 1 integer field MultiInts – 20 integer fields StringTree – 32 String fields • Serialization is the performance killer. • Small overhead when using objects as arguments. Serialization used in all cases. • Big overhead when using primitives. Serialization not used by normal RMI, but used by proxies.
Conclusion • RMI lacks flexibility necessary for separating service from application specific code. • Smart proxies and interceptors are useful tools for that task. • Using the dynamic proxy API and Java code mobility it is possible to create a lightweight framework for smart proxies and interceptors.
Source code and documentation available at: http://sourceforge.net/projects/smartrmi/ Questions?