Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » invocation » local » [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.local;
   23   
   24   import java.net.InetAddress;
   25   import java.security.AccessController;
   26   import java.security.PrivilegedAction;
   27   import java.security.PrivilegedExceptionAction;
   28   import java.security.PrivilegedActionException;
   29   import javax.management.ObjectName;
   30   import javax.naming.InitialContext;
   31   import javax.transaction.TransactionManager;
   32   
   33   import org.jboss.invocation.Invocation;
   34   import org.jboss.invocation.Invoker;
   35   import org.jboss.invocation.InvokerInterceptor;
   36   import org.jboss.mx.util.JMXExceptionDecoder;
   37   import org.jboss.proxy.TransactionInterceptor;
   38   import org.jboss.system.Registry;
   39   import org.jboss.system.ServiceMBeanSupport;
   40   
   41   /**
   42    * The Invoker is a local gate in the JMX system.
   43    *
   44    * @author <a href="mailto:marc.fleury@jboss.org>Marc Fleury</a>
   45    * @author Scott.Stark@jboss.org
   46    * @version $Revision: 37459 $
   47    * @jmx:mbean extends="org.jboss.system.ServiceMBean"
   48    */
   49   public class LocalInvoker
   50      extends ServiceMBeanSupport
   51      implements Invoker, LocalInvokerMBean
   52   {
   53      private MBeanServerAction serverAction = new MBeanServerAction();
   54   
   55      protected void createService() throws Exception
   56      {
   57         // note on design: We need to call it ourselves as opposed to 
   58         // letting the client InvokerInterceptor look it 
   59         // up through the use of Registry, the reason being including
   60         // the classes in the client. 
   61         // If we move to a JNDI format (with local calls) for the
   62         // registry we could remove the call below
   63         InvokerInterceptor.setLocal(this);
   64   
   65         Registry.bind(serviceName, this);
   66      }
   67   
   68      protected void startService() throws Exception
   69      {
   70         InitialContext ctx = new InitialContext();
   71         try
   72         {
   73   
   74            /**
   75             * FIXME marcf: what is this doing here?
   76             */
   77            TransactionManager tm = (TransactionManager) ctx.lookup("java:/TransactionManager");
   78            TransactionInterceptor.setTransactionManager(tm);
   79         }
   80         finally
   81         {
   82            ctx.close();
   83         }
   84   
   85         log.debug("Local invoker for JMX node started");
   86      }
   87   
   88      protected void destroyService()
   89      {
   90         Registry.unbind(serviceName);
   91      }
   92      
   93      // Invoker implementation --------------------------------
   94      
   95      public String getServerHostName()
   96      {
   97         try
   98         {
   99            return InetAddress.getLocalHost().getHostName();
  100         }
  101         catch (Exception ignored)
  102         {
  103            return null;
  104         }
  105      }
  106   
  107      /**
  108       * Invoke a method.
  109       */
  110      public Object invoke(Invocation invocation) throws Exception
  111      {
  112         ClassLoader oldCl = TCLAction.UTIL.getContextClassLoader();
  113   
  114         ObjectName mbean = (ObjectName) Registry.lookup((Integer) invocation.getObjectName());
  115         try
  116         {
  117            Object[] args = {invocation};
  118            Object rtnValue = serverAction.invoke(mbean, "invoke", args,
  119               Invocation.INVOKE_SIGNATURE);
  120            return rtnValue;
  121         }
  122         catch (Exception e)
  123         {
  124            e = (Exception) JMXExceptionDecoder.decode(e);
  125            if (log.isTraceEnabled())
  126               log.trace("Failed to invoke on mbean: " + mbean, e);
  127            throw e;
  128         }
  129         finally
  130         {
  131            TCLAction.UTIL.setContextClassLoader(oldCl);
  132         }
  133      }
  134   
  135      /** Perform the MBeanServer.invoke op in a PrivilegedExceptionAction if
  136       * running with a security manager.
  137       */ 
  138      class MBeanServerAction implements PrivilegedExceptionAction
  139      {
  140         private ObjectName target;
  141         String method;
  142         Object[] args;
  143         String[] sig;
  144   
  145         MBeanServerAction()
  146         {  
  147         }
  148         MBeanServerAction(ObjectName target, String method, Object[] args, String[] sig)
  149         {
  150            this.target = target;
  151            this.method = method;
  152            this.args = args;
  153            this.sig = sig;
  154         }
  155   
  156         public Object run() throws Exception
  157         {
  158            Object rtnValue = server.invoke(target, method, args, sig);
  159            return rtnValue;
  160         }
  161         Object invoke(ObjectName target, String method, Object[] args, String[] sig)
  162            throws Exception
  163         {
  164            SecurityManager sm = System.getSecurityManager();
  165            Object rtnValue = null;
  166            if( sm == null )
  167            {
  168               // Direct invocation on MBeanServer
  169               rtnValue = server.invoke(target, method, args, sig);
  170            }
  171            else
  172            {
  173               try
  174               {
  175                  // Encapsulate the invocation in a PrivilegedExceptionAction
  176                  MBeanServerAction action = new MBeanServerAction(target, method, args, sig);
  177                  rtnValue = AccessController.doPrivileged(action);
  178               }
  179               catch (PrivilegedActionException e)
  180               {
  181                  Exception ex = e.getException();
  182                  throw ex;
  183               }
  184            }
  185            return rtnValue;
  186         }
  187      }
  188   
  189      interface TCLAction
  190      {
  191         class UTIL
  192         {
  193            static TCLAction getTCLAction()
  194            {
  195               return System.getSecurityManager() == null ? NON_PRIVILEGED : PRIVILEGED;
  196            }
  197   
  198            static ClassLoader getContextClassLoader()
  199            {
  200               return getTCLAction().getContextClassLoader();
  201            }
  202   
  203            static ClassLoader getContextClassLoader(Thread thread)
  204            {
  205               return getTCLAction().getContextClassLoader(thread);
  206            }
  207   
  208            static void setContextClassLoader(ClassLoader cl)
  209            {
  210               getTCLAction().setContextClassLoader(cl);
  211            }
  212   
  213            static void setContextClassLoader(Thread thread, ClassLoader cl)
  214            {
  215               getTCLAction().setContextClassLoader(thread, cl);
  216            }
  217         }
  218   
  219         TCLAction NON_PRIVILEGED = new TCLAction()
  220         {
  221            public ClassLoader getContextClassLoader()
  222            {
  223               return Thread.currentThread().getContextClassLoader();
  224            }
  225   
  226            public ClassLoader getContextClassLoader(Thread thread)
  227            {
  228               return thread.getContextClassLoader();
  229            }
  230   
  231            public void setContextClassLoader(ClassLoader cl)
  232            {
  233               Thread.currentThread().setContextClassLoader(cl);
  234            }
  235   
  236            public void setContextClassLoader(Thread thread, ClassLoader cl)
  237            {
  238               thread.setContextClassLoader(cl);
  239            }
  240         };
  241   
  242         TCLAction PRIVILEGED = new TCLAction()
  243         {
  244            private final PrivilegedAction getTCLPrivilegedAction = new PrivilegedAction()
  245            {
  246               public Object run()
  247               {
  248                  return Thread.currentThread().getContextClassLoader();
  249               }
  250            };
  251   
  252            public ClassLoader getContextClassLoader()
  253            {
  254               return (ClassLoader)AccessController.doPrivileged(getTCLPrivilegedAction);
  255            }
  256   
  257            public ClassLoader getContextClassLoader(final Thread thread)
  258            {
  259               return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction()
  260               {
  261                  public Object run()
  262                  {
  263                     return thread.getContextClassLoader();
  264                  }
  265               });
  266            }
  267   
  268            public void setContextClassLoader(final ClassLoader cl)
  269            {
  270               AccessController.doPrivileged(
  271                  new PrivilegedAction()
  272                  {
  273                     public Object run()
  274                     {
  275                        Thread.currentThread().setContextClassLoader(cl);
  276                        return null;
  277                     }
  278                  }
  279               );
  280            }
  281   
  282            public void setContextClassLoader(final Thread thread, final ClassLoader cl)
  283            {
  284               AccessController.doPrivileged(
  285                  new PrivilegedAction()
  286                  {
  287                     public Object run()
  288                     {
  289                        thread.setContextClassLoader(cl);
  290                        return null;
  291                     }
  292                  }
  293               );
  294            }
  295         };
  296   
  297         ClassLoader getContextClassLoader();
  298   
  299         ClassLoader getContextClassLoader(Thread thread);
  300   
  301         void setContextClassLoader(ClassLoader cl);
  302   
  303         void setContextClassLoader(Thread thread, ClassLoader cl);
  304      }
  305   }
  306   

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