Class TransparentItemProxy

  • All Implemented Interfaces:
    java.io.Serializable, java.lang.reflect.InvocationHandler

    public final class TransparentItemProxy
    extends java.lang.Object
    implements java.lang.reflect.InvocationHandler, java.io.Serializable
    This class creates an object, representing a server item. The returned object will implement a list of interfaces defined by the client. The interfaces are completely independent of interfaces the server object implements, if any; they are simply logical groupings, of interest solely to the client. The interface methods 'should' declare that they throw java.lang.Exception: However, the Java dynamic proxy mechanism very dubiously allows this to be optional.

    Clients can dynamically create an item wrapper classes implementing any combination of interfaces. Combining interfaces provides a very important second order of abstraction. Whereas an interface is considered to be a grouping of functionality; the 'purpose' of an item, could be determined by the group of interfaces it implements. Clients can customise the way they use remote items as a function of the interfaces implemented.

    The proxy instances returned from this class are serialisable. Proxies can be persisted to storage for later use, and passed to other JVMs over the network. However, the item referenced by the proxy must also be serialisable necessarily, in order for this feature to work.

    If an item can be best represented with a single interface, it might be well to consider using a Wrapper class instead. It is conceptually much simpler, though lacks the syntactical transparency.

    Note: Unfortunately, this class only works with JREs 1.3 and higher. Therefore I was reluctant to include it in the official codebase. However, some very convincing discussion in the cajo project Developer's forum, with project member Bharavi Gade, caused me to reconsider.

    Version:
    1.1, 11-Nov-05 Support multiple interfaces
    See Also:
    Serialized Form
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static java.lang.Object handler
      An optional centralised invocation error handler.
      private java.lang.Object item  
      private static java.lang.Object[] NULL  
      private static long serialVersionUID  
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private TransparentItemProxy​(java.lang.Object item)  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static java.lang.Object getItem​(java.lang.Object item, java.lang.Class[] interfaces)
      This generates a class definition for a remote object reference at runtime, and returns a local object instance.
      static java.lang.Object getItem​(java.lang.String url, java.lang.Class[] interfaces)
      This method fetches a server item reference, generates a class definition for it at runtime, and returns a local object instance.
      java.lang.Object invoke​(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
      This method, inherited from InvocationHandler, simply passes all object method invocations on to the remote object, automatically and transparently.
      private void writeObject​(java.io.ObjectOutputStream out)  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • NULL

        private static final java.lang.Object[] NULL
      • item

        private java.lang.Object item
      • handler

        public static java.lang.Object handler
        An optional centralised invocation error handler. If an invocation on a remote object results in a checked or unchecked exception being thrown; this object, if assigned, will be called to deal with it. This allows all retry/recovery/rollback logic, etc. to be located in a single place. It is expected that this object will implement a method of the following signature:

        public Object handle(Object item, String method, Object args[], Throwable t) throws Throwable;

        The first arguments are as follows:

        • the remote item reference on which the method was being invoked
        • the method that was called on the remote object
        • the arguments that were provided in the method call
        • the error that resulted from the invocation
        The handler will either successfully recover from the error, and return the appropriate result, or throw a hopefully more descriptive error.
    • Constructor Detail

      • TransparentItemProxy

        private TransparentItemProxy​(java.lang.Object item)
    • Method Detail

      • writeObject

        private void writeObject​(java.io.ObjectOutputStream out)
                          throws java.io.IOException
        Throws:
        java.io.IOException
      • invoke

        public java.lang.Object invoke​(java.lang.Object proxy,
                                       java.lang.reflect.Method method,
                                       java.lang.Object[] args)
                                throws java.lang.Throwable
        This method, inherited from InvocationHandler, simply passes all object method invocations on to the remote object, automatically and transparently. This allows the local runtime to perform remote item invocations, while appearing syntactically identical to local ones.
        Specified by:
        invoke in interface java.lang.reflect.InvocationHandler
        Parameters:
        proxy - The locallly created proxy object on which the method was originally invoked.
        method - The method to invoke on the object, in this case the server item.
        args - The arguments to provide to the method, if any.
        Returns:
        The resulting data from the method invocation, if any.
        Throws:
        java.rmi.RemoteException - For network communication related reasons.
        java.lang.NoSuchMethodException - If no matching method can be found on the server item.
        java.lang.Exception - If the server item rejected the invocation, for application specific reasons.
        java.lang.Throwable - For some very unlikely reasons, not outlined above. (required, sorry)
      • getItem

        public static java.lang.Object getItem​(java.lang.Object item,
                                               java.lang.Class[] interfaces)
        This generates a class definition for a remote object reference at runtime, and returns a local object instance. The resulting dynamic proxy object will implement all the interfaces provided. Note: if this proxy object is to be passed between JVMs, the item must be either serialisable (as a completely local proxy) or be wrapped in a gnu.cajo.invoke.Remote wrapper.
        Parameters:
        item - A reference to a presumably remote server object; a local object instance could be used as well; to distinguish between these two cases, proxies to remote objects will also implement the marker interface java.rmi.Remote, on which the proxy may be tested via the instanceof operator. Note: a non-serialisable local item will be automatically remoted when serialised, so as to allow the proxies to be passed between JVMs.
        interfaces - The list of interface classes for the dynamic proxy to implement. Typically, these are provided thus; new Class[] { Interface1.class, Interface2.class, ... }
        Returns:
        A reference to the server item, wrapped in the local object, created at runtime. It can then be typecast into any of the interfaces, as needed by the client. Note: if the item reference is to an object in a remote JVM, the returned proxy will also implement the marker interface java.rmi.Remote, to allow this fact to be easily tested, via the instanceof operator.
      • getItem

        public static java.lang.Object getItem​(java.lang.String url,
                                               java.lang.Class[] interfaces)
                                        throws java.rmi.RemoteException,
                                               java.rmi.NotBoundException,
                                               java.io.IOException,
                                               java.lang.ClassNotFoundException,
                                               java.lang.InstantiationException,
                                               java.lang.IllegalAccessException,
                                               java.net.MalformedURLException
        This method fetches a server item reference, generates a class definition for it at runtime, and returns a local object instance. The resulting dynamic proxy object will implement all the interfaces provided. Technically, it invokes the other getItem method, after fetching the object reference from the remote JVM specified.
        Parameters:
        url - The URL where to get the object: //[host][:port]/[name]. The host, port, and name, are all optional. If missing the host is presumed local, the port 1099, and the name "main". If the URL is null, it will be assumed to be ///.
        interfaces - The list of interface classes for the dynamic proxy to implement. Typically, these are provided thus; new Class[] { Interface1.class, Interface2.class, ... }
        Returns:
        A reference to the server item, wrapped in the object created at runtime, implementing all of the interfaces provided. It can then be typecast into any of the interfaces, as needed by the client.
        Throws:
        java.rmi.RemoteException - if the remote registry could not be reached.
        java.rmi.NotBoundException - if the requested name is not in the registry.
        java.io.IOException - if the zedmob format is invalid.
        java.lang.ClassNotFoundException - if a proxy was sent to the VM, and proxy hosting was not enabled.
        java.lang.InstantiationException - when the URL specifies a class name which cannot be instantiated at runtime.
        java.lang.IllegalAccessException - when the url specifies a class name and it does not support a no-arg constructor.
        java.net.MalformedURLException - if the URL is not in the format explained