net.jini.activation
Class ActivatableInvocationHandler

java.lang.Object
  extended by net.jini.activation.ActivatableInvocationHandler
All Implemented Interfaces:
Serializable, InvocationHandler, TrustEquivalence

public final class ActivatableInvocationHandler
extends Object
implements InvocationHandler, TrustEquivalence, Serializable

An invocation handler for activatable remote objects. If the client constraints of this activatable invocation handler are not null, then the invocation handler's underlying proxy (if any) must implement RemoteMethodControl or a remote invocation will fail with an UnsupportedConstraintException.

Since:
2.0
Author:
Sun Microsystems, Inc.
See Also:
Serialized Form
Implementation Specifics:
This implementation recognizes the following system property:

This implementation's invoke method throws IllegalArgumentException if a remote invocation is to be made and the proxy argument is an instance of an interface whose binary name is javax.management.MBeanServerConnection or any of the names produced by the following procedure:

For each resource named com/sun/jini/proxy/resources/InvocationHandler.moreProhibitedProxyInterfaces that is visible to the system class loader, the contents of the resource are parsed as UTF-8 text to produce a list of interface names. The resource must contain a list of binary names of interfaces, one per line. Space and tab characters surrounding each name, as well as blank lines, are ignored. The comment character is '#'; on each line, all characters starting with the first comment character are ignored.

This implementation uses the Logger named net.jini.activation.ActivatableInvocationHandler to log information at the following levels:

Level Description
FAILED exception thrown from final attempt to communicate a remote call
FAILED exception thrown activating the object
HANDLED exception caught in attempt to communicate a remote call

Nested Class Summary
private static class ActivatableInvocationHandler.Failure
          Holds information about the communication failure of a remote call attempt.
 
Field Summary
private  MethodConstraints clientConstraints
          The client constraints or null.
private static Class[] constructorArgs
          Constructor parameter classes for proxy classes.
private static boolean enableGrant
          Flag to enable use of Security.grant.
private static Method getPtiMethod
           
private  ActivationID id
          The activation identifier.
private static Logger logger
          logger
private static int MAX_RETRIES
          The number of times to retry a call, with varying degrees of reactivation in between.
private static long serialVersionUID
           
private  Remote uproxy
          The underlying proxy or null.
 
Constructor Summary
  ActivatableInvocationHandler(ActivationID id, Remote underlyingProxy)
          Creates an instance with the specified activation identifier, a possibly-null underlying proxy, and null client constraints.
private ActivatableInvocationHandler(ActivationID id, Remote underlyingProxy, MethodConstraints clientConstraints)
          Creates an instance with the specified activation identifier, optional underlying proxy, and client constraints.
 
Method Summary
private  void activate(boolean force, Object proxy, Method method)
          Activate the object (see activate0).
private  void activate0(boolean force, Object proxy)
          Activate the object and update the underlying proxy.
 boolean checkTrustEquivalence(Object obj)
          Returns true if the specified object (which is not yet known to be trusted) is equivalent in trust, content, and function to this known trusted object, and false otherwise.
 boolean equals(Object obj)
          Compares the specified object with this ActivatableInvocationHandler for equality.
 ActivationID getActivationID()
          Returns the activation identifier supplied during construction of this invocation handler.
 Object getCurrentProxy()
          Returns the current value for the underlying proxy.
private static ClassLoader getProxyLoader(Class proxyClass)
          Returns the class loader for the specified proxy class.
protected  ProxyTrustIterator getProxyTrustIterator()
          Returns a proxy trust iterator for an activatable object that is suitable for use by ProxyTrustVerifier.
private  boolean hasConsistentConstraints()
          Returns true if the constraints on the underlying proxy (if it implements RemoteMethodControl) are equivalent to the constraints of this invocation handler, or if the underlying proxy does not implement RemoteMethodControl.
 int hashCode()
          Returns a hash code value for this object.
 Object invoke(Object proxy, Method method, Object[] args)
          Processes a method invocation made on the encapsulating proxy instance, proxy, and returns the result.
private  Object invokeMethod(Object proxy, Method m, Object[] args)
          Reflectively invokes the method on the supplied proxy and returns the result in a Result object.
private static Object invokeMethod0(Object proxy, Method m, Object[] args)
          Reflectively invokes the method on the supplied proxy as follows: If the method's declaring class is not public, the proxy is an instance of the method's declaring class, and the proxy class is public, a public method with the same name and parameter types is obtained from the proxy class, and if such a method exists, that method is reflectively invoked on the proxy passing it the specified args and the result is returned, otherwise if such a method doesn't exist an ActivateFailedException is thrown with NoSuchMethodException as the cause.
private  Object invokeObjectMethod(Object proxy, Method method, Object[] args)
          Handles java.lang.Object methods.
private  Object invokeRemoteMethod(Object proxy, Method method, Object[] args)
          Handles remote methods.
private  Object invokeRemoteMethodControlMethod(Object proxy, Method method, Object[] args)
          Handles RemoteMethodControl methods.
private  Object invokeTrustEquivalenceMethod(Object proxy, Method method, Object[] args)
          Handles TrustEquivalence methods.
private  void logThrow(Level level, String logRecordText, String sourceMethodName, Method method, Throwable t)
          Log the throw of an outbound remote call.
private  String proxyToString(Object proxy)
          Returns a string representation for a proxy that uses this invocation handler.
private  void readObject(ObjectInputStream s)
          Verifies that the activation identifier is not null, and that the constraints on this invocation handler and the underlying proxy are consistent.
 String toString()
          Returns a string representation of this object.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

serialVersionUID

private static final long serialVersionUID
See Also:
Constant Field Values

MAX_RETRIES

private static final int MAX_RETRIES
The number of times to retry a call, with varying degrees of reactivation in between.

See Also:
Constant Field Values

logger

private static final Logger logger
logger


constructorArgs

private static final Class[] constructorArgs
Constructor parameter classes for proxy classes.


enableGrant

private static final boolean enableGrant
Flag to enable use of Security.grant.


id

private final ActivationID id
The activation identifier.


uproxy

private Remote uproxy
The underlying proxy or null.


clientConstraints

private final MethodConstraints clientConstraints
The client constraints or null.


getPtiMethod

private static final Method getPtiMethod
Constructor Detail

ActivatableInvocationHandler

public ActivatableInvocationHandler(ActivationID id,
                                    Remote underlyingProxy)
Creates an instance with the specified activation identifier, a possibly-null underlying proxy, and null client constraints. If the underlying proxy implements RemoteMethodControl and its constraints are not null, the underlying proxy of this instance is a copy of that proxy with null constraints.

Parameters:
id - the activation identifier
underlyingProxy - an underlying proxy, or null
Throws:
NullPointerException - if id is null

ActivatableInvocationHandler

private ActivatableInvocationHandler(ActivationID id,
                                     Remote underlyingProxy,
                                     MethodConstraints clientConstraints)
Creates an instance with the specified activation identifier, optional underlying proxy, and client constraints. This constructor assumes that the client constraints are equivalent to the constraints on the underlying proxy.

Method Detail

hasConsistentConstraints

private boolean hasConsistentConstraints()
Returns true if the constraints on the underlying proxy (if it implements RemoteMethodControl) are equivalent to the constraints of this invocation handler, or if the underlying proxy does not implement RemoteMethodControl.


getActivationID

public ActivationID getActivationID()
Returns the activation identifier supplied during construction of this invocation handler.

Returns:
the activation identifier

getCurrentProxy

public Object getCurrentProxy()
Returns the current value for the underlying proxy.

Returns:
the underlying proxy

invoke

public Object invoke(Object proxy,
                     Method method,
                     Object[] args)
              throws Throwable
Processes a method invocation made on the encapsulating proxy instance, proxy, and returns the result. This method is invoked when a method is invoked on a proxy instance that this handler is associated with.

If the specified method is one of the following java.lang.Object methods, it will be processed as follows:

If the specified method is RemoteMethodControl.setConstraints, then if proxy is an instance of a dynamic proxy class containing this invocation handler, returns a new proxy containing a copy of this invocation handler with the same activation identifier, the new specified client constraints (args[0]), and the current underlying proxy, or if the current underlying proxy implements RemoteMethodControl, a copy of that proxy with the new specified client constraints. An exception is thrown if proxy is not an instance of a dynamic proxy class containing this invocation handler.

If the specified method is RemoteMethodControl.getConstraints, returns the client constraints.

If the specified method is TrustEquivalence.checkTrustEquivalence, returns true if the argument (args[0]) is an instance of a dynamic proxy class (that is, a class generated by Proxy) that implements the same interfaces as the specified proxy and calling the checkTrustEquivalence method of this invocation handler with the invocation handler of that argument returns true, and returns false otherwise.

For all other methods, a remote invocation is made as follows:

A single set of absolute constraints (if any) is used for the duration of the remote invocation, including any activation that may occur.

The implementation of remote method invocation defined by this class preserves at-most-once call semantics: the remote call either does not execute, partially executes, or executes exactly once at the remote site. Note that for remote calls to activatable objects, arguments may be marshalled more than once.

The semantics of this method are unspecified if the arguments could not have been produced by an instance of some valid dynamic proxy class containing this invocation handler. This method throws IllegalArgumentException if proxy is an instance of InvocationHandler or, if a remote invocation is to be made, any of the superinterfaces of proxy's class have a method with the same name and parameter types as method but that does not declare RemoteException or a superclass of RemoteException in its throws clause (even if such a method is not a member of any of the direct superinterfaces of proxy's class because of overriding).

Specified by:
invoke in interface InvocationHandler
Throws:
Throwable
See Also:
UndeclaredThrowableException

invokeObjectMethod

private Object invokeObjectMethod(Object proxy,
                                  Method method,
                                  Object[] args)
Handles java.lang.Object methods.


invokeRemoteMethodControlMethod

private Object invokeRemoteMethodControlMethod(Object proxy,
                                               Method method,
                                               Object[] args)
                                        throws Throwable
Handles RemoteMethodControl methods.

Throws:
Throwable

invokeTrustEquivalenceMethod

private Object invokeTrustEquivalenceMethod(Object proxy,
                                            Method method,
                                            Object[] args)
Handles TrustEquivalence methods.


invokeRemoteMethod

private Object invokeRemoteMethod(Object proxy,
                                  Method method,
                                  Object[] args)
                           throws Throwable
Handles remote methods.

Throws:
Throwable

logThrow

private void logThrow(Level level,
                      String logRecordText,
                      String sourceMethodName,
                      Method method,
                      Throwable t)
Log the throw of an outbound remote call.


invokeMethod

private Object invokeMethod(Object proxy,
                            Method m,
                            Object[] args)
                     throws Throwable
Reflectively invokes the method on the supplied proxy and returns the result in a Result object. If a RemoteException is thrown as a result of the remote invocation, then the result object contains a non-null exception and the retry field indicates whether invocation retry is possible without violating "at-most-once" call semantics. If the result object contains a null exception, then the value field is the return value of the remote invocation.

Throws:
Throwable

invokeMethod0

private static Object invokeMethod0(Object proxy,
                                    Method m,
                                    Object[] args)
                             throws Throwable
Reflectively invokes the method on the supplied proxy as follows:

If the method's declaring class is not public, the proxy is an instance of the method's declaring class, and the proxy class is public, a public method with the same name and parameter types is obtained from the proxy class, and if such a method exists, that method is reflectively invoked on the proxy passing it the specified args and the result is returned, otherwise if such a method doesn't exist an ActivateFailedException is thrown with NoSuchMethodException as the cause.

Otherwise, the original method is reflectively invoked on the proxy passing it the specified args and the result is returned.

If the reflective invocation throws IllegalAccessException or IllegalArgumentException, an ActivateFailedException exception is thrown with the original exception as the cause. If the reflective invocation throws InvocationTargetException the contained target exception is thrown.

Parameters:
proxy - a proxy
m - a method
args - arguments
Returns:
result of reflective invocation
Throws:
ActivateFailedException - if the reflective invocation throws IllegalAccessException or IllegalArgumentException
Throwable - if the reflective invocation throws InvocationTargetException, the contained target exception is thrown

getProxyTrustIterator

protected ProxyTrustIterator getProxyTrustIterator()
Returns a proxy trust iterator for an activatable object that is suitable for use by ProxyTrustVerifier.

The iterator produces the current underlying proxy on each iteration. The iterator produces up to three elements, but after the first element, iteration terminates unless the exception set by a call to setException on the previous iteration is an instance of ConnectException, ConnectIOException, NoSuchObjectException, or UnknownHostException.

On each iteration, if the current underlying proxy is null or the same as the underlying proxy produced by the previous iteration:

A new proxy is obtained by invoking the activate method on the activation identifier, passing false as the argument. That method must return an instance of a dynamic Proxy class, with an invocation handler that is an instance of this class, containing the same activation identifier. If this activation throws one of the following exceptions, the exception is thrown by the next method of the iterator and the iteration terminates:

If the proxy returned by the activate call does not meet the criteria listed above, then an ActivateFailedException is thrown. If the activate call throws RemoteException, then ConnectIOException is thrown with the RemoteException as the cause. If the activate call throws UnknownHostException, then NoSuchObjectException is thrown with the UnknownHostException as the cause. Finally, if the activate call throws ActivationException, then ActivateFailedException is thrown with the ActivationException as the cause.

If a valid, new proxy is returned by the activate call, the underlying proxy of the new proxy is obtained from the new proxy's activatable invocation handler. If the obtained underlying proxy implements RemoteMethodControl, this invocation handler's underlying proxy is set to a copy of the obtained underlying proxy with the client constraints of this instance. Otherwise, this invocation handler's underlying proxy is set to the obtained underlying proxy.

On the first call to the activation identifier's activate method, false is passed as an argument; on subsequent calls true will be passed, if passing false returned the same underlying proxy as before (when compared using the equals method) or if the exception passed to setException is an instance of NoSuchObjectException. If an activation attempt results in an exception, that exception is thrown by the next method of the iterator and iteration terminates.

Returns:
a proxy trust iterator suitable for use by ProxyTrustVerifier

checkTrustEquivalence

public boolean checkTrustEquivalence(Object obj)
Returns true if the specified object (which is not yet known to be trusted) is equivalent in trust, content, and function to this known trusted object, and false otherwise.

ActivatableInvocationHandler implements this method as follows:

This method returns true if and only if the following conditions are met:

The underlying proxy of the specified object is set to null if this method returns true and any of the following conditions are met:

Specified by:
checkTrustEquivalence in interface TrustEquivalence
Parameters:
obj - object to check that is not yet known to be trusted
Returns:
true if the specified object (that is not yet known to be trusted) is equivalent in trust, content, and function to this known trusted object, and returns false otherwise

activate

private void activate(boolean force,
                      Object proxy,
                      Method method)
               throws Exception
Activate the object (see activate0).

Throws:
Exception

activate0

private void activate0(boolean force,
                       Object proxy)
                throws RemoteException
Activate the object and update the underlying proxy. The force argument is passed on to the activate method of the activation identifier. If this method does not throw an exception, the value of uproxy is updated to the value returned by calling the id's activate method. Note: The caller should be synchronized on "this" while calling this method.

Parameters:
force - boolean to pass to activation id's activate method
proxy - outer proxy from which dynamic grants are inherited, or null
Throws:
RemoteException

equals

public boolean equals(Object obj)
Compares the specified object with this ActivatableInvocationHandler for equality.

This method returns true if and only if the specified object has the same class as this object, and the activation identifier and client constraints in the specified object are equal to the ones in this object.

Overrides:
equals in class Object

hashCode

public int hashCode()
Returns a hash code value for this object.

Overrides:
hashCode in class Object

toString

public String toString()
Returns a string representation of this object.

Overrides:
toString in class Object

proxyToString

private String proxyToString(Object proxy)
Returns a string representation for a proxy that uses this invocation handler.


readObject

private void readObject(ObjectInputStream s)
                 throws IOException,
                        ClassNotFoundException
Verifies that the activation identifier is not null, and that the constraints on this invocation handler and the underlying proxy are consistent.

Throws:
InvalidObjectException - if the activation identifier is null, or if the underlying proxy implements RemoteMethodControl and the constraints on the underlying proxy are not equivalent to this invocation handler's constraints
IOException
ClassNotFoundException

getProxyLoader

private static ClassLoader getProxyLoader(Class proxyClass)
Returns the class loader for the specified proxy class.



Copyright 2007-2010, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.