Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.invocation.jrmp » interfaces » [javadoc | source]
    1   /*
    2   * JBoss, Home of Professional Open Source
    3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
    4   * by the @authors tag. See the copyright.txt in the distribution for a
    5   * full listing of individual contributors.
    6   *
    7   * This is free software; you can redistribute it and/or modify it
    8   * under the terms of the GNU Lesser General Public License as
    9   * published by the Free Software Foundation; either version 2.1 of
   10   * the License, or (at your option) any later version.
   11   *
   12   * This software is distributed in the hope that it will be useful,
   13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15   * Lesser General Public License for more details.
   16   *
   17   * You should have received a copy of the GNU Lesser General Public
   18   * License along with this software; if not, write to the Free
   19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21   */
   22   package org.jboss.invocation.jrmp.interfaces;
   23   
   24   import java.io.IOException;
   25   import java.io.Externalizable;
   26   import java.io.ObjectInput;
   27   import java.io.ObjectOutput;
   28   import java.rmi.ConnectException;
   29   import java.rmi.MarshalledObject;
   30   import java.rmi.NoSuchObjectException;
   31   import java.rmi.RemoteException;
   32   import java.rmi.ServerException;
   33   import java.rmi.server.RemoteObject;
   34   import java.rmi.server.RemoteStub;
   35   import javax.transaction.TransactionRolledbackException;
   36   import javax.transaction.SystemException;
   37   
   38   import org.jboss.invocation.Invocation;
   39   import org.jboss.invocation.Invoker;
   40   import org.jboss.invocation.MarshalledInvocation;
   41   import org.jboss.tm.TransactionPropagationContextFactory;
   42   import org.jboss.tm.TransactionPropagationContextUtil;
   43   
   44   /**
   45    * JRMPInvokerProxy, local to the proxy and is capable of delegating to
   46    * the JRMP implementations
   47    *
   48    * @author <a href="mailto:marc.fleury@jboss.org">Marc Fleury</a>
   49    * @author <a href="mailto:scott.stark@jboss.org">Scott Stark</a>
   50    * @version $Revision: 37459 $
   51    */
   52   public class JRMPInvokerProxy
   53      implements Invoker, Externalizable
   54   {
   55      /** Serial Version Identifier. @since 1.7.2.4 */
   56      private  static final long serialVersionUID = -3713605626489646730L;
   57      // Attributes ----------------------------------------------------
   58   
   59      // Invoker to the remote JMX node
   60      protected Invoker remoteInvoker;
   61   
   62      /**
   63       * max retries on a ConnectException.
   64       */
   65      public static int MAX_RETRIES = 10;
   66   
   67      /**
   68       * Exposed for externalization.
   69       */
   70      public JRMPInvokerProxy()
   71      {
   72         super();
   73      }
   74   
   75      /**
   76       * Create a new Proxy.
   77       *
   78       * @param container    The remote interface of the container invoker of the
   79       *                     container we proxy for.
   80       */
   81      public JRMPInvokerProxy(final Invoker remoteInvoker)
   82      {
   83         this.remoteInvoker = remoteInvoker;
   84      }
   85   
   86      /**
   87       * The name of of the server.
   88       */
   89      public String getServerHostName() throws Exception
   90      {
   91         return remoteInvoker.getServerHostName();
   92      }
   93   
   94      /**
   95       * ???
   96       *
   97       * @todo: MOVE TO TRANSACTION
   98       *
   99       * @return the transaction propagation context of the transaction
  100       *         associated with the current thread.
  101       *         Returns <code>null</code> if the transaction manager was never
  102       *         set, or if no transaction is associated with the current thread.
  103       */
  104      public Object getTransactionPropagationContext()
  105         throws SystemException
  106      {
  107         TransactionPropagationContextFactory tpcFactory = TransactionPropagationContextUtil.getTPCFactoryClientSide();
  108         return (tpcFactory == null) ? null : tpcFactory.getTransactionPropagationContext();
  109      }
  110   
  111      /**
  112       * The invocation on the delegate, calls the right invoker.  Remote if we are remote,
  113       * local if we are local.
  114       * @todo Shouldn't we unwrap _ALL_ RemoteExceptions?
  115       */
  116      public Object invoke(Invocation invocation)
  117         throws Exception
  118      {
  119         // We are going to go through a Remote invocation, switch to a Marshalled Invocation
  120         MarshalledInvocation mi = new MarshalledInvocation(invocation);
  121   
  122         // Set the transaction propagation context
  123         //  @todo: MOVE TO TRANSACTION
  124         mi.setTransactionPropagationContext(getTransactionPropagationContext());
  125   
  126         // RMI seems to make a connection per invocation.
  127         // If too many clients are making an invocation
  128         // at same time, ConnectionExceptions happen
  129         for (int i = 0; i < MAX_RETRIES; i++)
  130         {
  131            try
  132            {
  133               MarshalledObject result = (MarshalledObject) remoteInvoker.invoke(mi);
  134               return result.get();
  135            }
  136            catch (ConnectException ce)
  137            {
  138               if (i + 1 < MAX_RETRIES)
  139               {
  140                  Thread.sleep(1);
  141                  continue;
  142               }
  143               throw ce;
  144            }
  145            catch (ServerException ex)
  146            {
  147               // Suns RMI implementation wraps NoSuchObjectException in
  148               // a ServerException. We cannot have that if we want
  149               // to comply with the spec, so we unwrap here.
  150               if (ex.detail instanceof NoSuchObjectException)
  151               {
  152                  throw (NoSuchObjectException) ex.detail;
  153               }
  154               if (ex.detail instanceof TransactionRolledbackException)
  155               {
  156                  throw (TransactionRolledbackException) ex.detail;
  157               }
  158               if (ex.detail instanceof RemoteException)
  159               {
  160                  throw (RemoteException) ex.detail;
  161               }
  162               throw ex;
  163            }
  164         }
  165         throw new Exception("Unreachable statement");
  166      }
  167   
  168      /**
  169       * Externalize this instance and handle obtaining the remoteInvoker stub
  170       */
  171      public void writeExternal(final ObjectOutput out)
  172         throws IOException
  173      {
  174         /** We need to handle obtaining the RemoteStub for the remoteInvoker
  175          * since this proxy may be serialized in contexts that are not JRMP
  176          * aware.
  177          */
  178         if( remoteInvoker instanceof RemoteStub )
  179         {
  180            out.writeObject(remoteInvoker);
  181         }
  182         else
  183         {
  184            Object replacement = RemoteObject.toStub(remoteInvoker);
  185            out.writeObject(replacement);
  186         }
  187      }
  188   
  189      /**
  190       * Un-externalize this instance.
  191       *
  192       */
  193      public void readExternal(final ObjectInput in)
  194         throws IOException, ClassNotFoundException
  195      {
  196         remoteInvoker = (Invoker) in.readObject();
  197      }
  198   }
  199   

Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.invocation.jrmp » interfaces » [javadoc | source]