Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » ejb » plugins » [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.ejb.plugins;
   23   
   24   import java.io.PrintWriter;
   25   import java.io.StringWriter;
   26   import java.rmi;
   27   import java.security.GeneralSecurityException;
   28   
   29   import javax.ejb.EJBException;
   30   import javax.ejb.NoSuchEntityException;
   31   import javax.ejb.NoSuchObjectLocalException;
   32   import javax.ejb.TransactionRolledbackLocalException;
   33   import javax.ejb.AccessLocalException;
   34   import javax.transaction.TransactionRolledbackException;
   35   
   36   
   37   import org.jboss.invocation.Invocation;
   38   import org.jboss.invocation.InvocationType;
   39   import org.jboss.invocation.JBossLazyUnmarshallingException;
   40   import org.jboss.metadata.BeanMetaData;
   41   
   42   import org.jboss.tm.JBossTransactionRolledbackException;
   43   import org.jboss.tm.JBossTransactionRolledbackLocalException;
   44   
   45   /**
   46    * An interceptor used to log all invocations. It also handles any
   47    * unexpected exceptions.
   48    *
   49    * @author <a href="mailto:rickard.oberg@telkel.com">Rickard Oberg</a>
   50    * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>
   51    * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
   52    * @author <a href="mailto:osh@sparre.dk">Ole Husgaard</a>
   53    * @version $Revision: 66439 $
   54    */
   55   public class LogInterceptor extends AbstractInterceptor
   56   {
   57      // Static --------------------------------------------------------
   58   
   59      // Attributes ----------------------------------------------------
   60      protected String ejbName;
   61      protected boolean callLogging;
   62   
   63      // Constructors --------------------------------------------------
   64   
   65      // Public --------------------------------------------------------
   66   
   67      // Container implementation --------------------------------------
   68      public void create()
   69         throws Exception
   70      {
   71         super.start();
   72   
   73         BeanMetaData md = getContainer().getBeanMetaData();
   74         ejbName = md.getEjbName();
   75   
   76         // Should we log call details
   77         callLogging = md.getContainerConfiguration().getCallLogging();
   78      }
   79   
   80      /**
   81       * This method logs the method, calls the next invoker, and handles
   82       * any exception.
   83       *
   84       * @param invocation contain all infomation necessary to carry out the
   85       * invocation
   86       * @return the return value of the invocation
   87       * @exception Exception if an exception during the invocation
   88       */
   89      public Object invokeHome(Invocation invocation)
   90         throws Exception
   91      {
   92         String methodName;
   93         if (invocation.getMethod() != null)
   94         {
   95            methodName = invocation.getMethod().getName();
   96         }
   97         else
   98         {
   99            methodName = "<no method>";
  100         }
  101   
  102         boolean trace = log.isTraceEnabled();
  103         if (trace)
  104         {
  105            log.trace("Start method=" + methodName);
  106         }
  107   
  108         // Log call details
  109         if (callLogging)
  110         {
  111            StringBuffer str = new StringBuffer("InvokeHome: ");
  112            str.append(methodName);
  113            str.append("(");
  114            Object[] args = invocation.getArguments();
  115            if (args != null)
  116            {
  117               for (int i = 0; i < args.length; i++)
  118               {
  119                  if (i > 0)
  120                  {
  121                     str.append(",");
  122                  }
  123                  str.append(args[i]);
  124               }
  125            }
  126            str.append(")");
  127            log.debug(str.toString());
  128         }
  129   
  130         try
  131         {
  132            return getNext().invokeHome(invocation);
  133         }
  134         catch(Throwable e)
  135         {
  136            throw handleException(e, invocation);
  137         }
  138         finally
  139         {
  140            if (trace)
  141            {
  142               log.trace("End method=" + methodName);
  143            }
  144         }
  145      }
  146   
  147      /**
  148       * This method logs the method, calls the next invoker, and handles
  149       * any exception.
  150       *
  151       * @param invocation contain all infomation necessary to carry out the
  152       * invocation
  153       * @return the return value of the invocation
  154       * @exception Exception if an exception during the invocation
  155       */
  156      public Object invoke(Invocation invocation)
  157         throws Exception
  158      {
  159         String methodName;
  160         if (invocation.getMethod() != null)
  161         {
  162            methodName = invocation.getMethod().getName();
  163         }
  164         else
  165         {
  166            methodName = "<no method>";
  167         }
  168   
  169         boolean trace = log.isTraceEnabled();
  170         if (trace)
  171         {
  172            log.trace("Start method=" + methodName);
  173         }
  174   
  175         // Log call details
  176         if (callLogging)
  177         {
  178            StringBuffer str = new StringBuffer("Invoke: ");
  179            if (invocation.getId() != null)
  180            {
  181               str.append("[");
  182               str.append(invocation.getId().toString());
  183               str.append("] ");
  184            }
  185            str.append(methodName);
  186            str.append("(");
  187            Object[] args = invocation.getArguments();
  188            if (args != null)
  189            {
  190               for (int i = 0; i < args.length; i++)
  191               {
  192                  if (i > 0)
  193                  {
  194                     str.append(",");
  195                  }
  196                  str.append(args[i]);
  197               }
  198            }
  199            str.append(")");
  200            log.debug(str.toString());
  201         }
  202   
  203         try
  204         {
  205            return getNext().invoke(invocation);
  206         }
  207         catch(Throwable e)
  208         {
  209            throw handleException(e, invocation);
  210         }
  211         finally
  212         {
  213            if (trace)
  214            {
  215               log.trace("End method=" + methodName);
  216            }
  217         }
  218      }
  219   
  220      // Private -------------------------------------------------------
  221   
  222      /**
  223       PLEASE DO NOT CHANGE THIS CODE WITHOUT LOOKING AT __ALL__ OF IT TO MAKE ___SURE___
  224       YOUR CHANGES ARE NECESSARY AND DO NOT BREAK LARGE AMOUNTS OF CORRECT BEHAVIOR!
  225       PLEASE ADD A TEST TO DEMONSTRATE YOUR CHANGES FIX SOMETHING.
  226       The rollback exceptions are tested by org.jboss.test.jca.test.XAExceptionUnitTestCase
  227       * @param e - the exception thrown by the invocation
  228       * @param invocation
  229       * @return the correct exception to throw
  230       */ 
  231      private Exception handleException(Throwable e, Invocation invocation)
  232      {
  233   
  234         InvocationType type = invocation.getType();
  235         boolean isLocal =
  236               type == InvocationType.LOCAL ||
  237               type == InvocationType.LOCALHOME;
  238   
  239         if (e instanceof TransactionRolledbackLocalException ||
  240               e instanceof TransactionRolledbackException)
  241         {
  242            // If we got a remote TransactionRolledbackException for a local
  243            // invocation convert it into a TransactionRolledbackLocalException
  244            if (isLocal && e instanceof TransactionRolledbackException)
  245            {
  246               TransactionRolledbackException remoteTxRollback =
  247                     (TransactionRolledbackException)e;
  248   
  249               Exception cause;
  250               if (remoteTxRollback.detail instanceof Exception)
  251               {
  252                  cause = (Exception)remoteTxRollback.detail;
  253               }
  254               else if (remoteTxRollback.detail instanceof Error)
  255               {
  256                  String msg = formatException(
  257                        "Unexpected Error",
  258                        remoteTxRollback.detail);
  259                  cause = new EJBException(msg);
  260               }
  261               else
  262               {
  263                  String msg = formatException(
  264                        "Unexpected Throwable",
  265                        remoteTxRollback.detail);
  266                  cause = new EJBException(msg);
  267               }
  268   
  269               e = new JBossTransactionRolledbackLocalException(
  270                     remoteTxRollback.getMessage(),
  271                     cause);
  272            }
  273   
  274            // If we got a local TransactionRolledbackLocalException for a remote
  275            // invocation convert it into a TransactionRolledbackException
  276            if (!isLocal && e instanceof TransactionRolledbackLocalException)
  277            {
  278               TransactionRolledbackLocalException localTxRollback =
  279                     (TransactionRolledbackLocalException)e;
  280               e = new JBossTransactionRolledbackException(
  281                     localTxRollback.getMessage(), localTxRollback.getCausedByException());
  282            }
  283   
  284            // get the data we need for logging
  285            Throwable cause = null;
  286            String exceptionType = null;
  287            if (e instanceof TransactionRolledbackException)
  288            {
  289               cause = ((TransactionRolledbackException)e).detail;
  290               exceptionType = "TransactionRolledbackException";
  291            }
  292            else
  293            {
  294               cause =
  295                  ((TransactionRolledbackLocalException)e).getCausedByException();
  296               exceptionType = "TransactionRolledbackLocalException";
  297            }
  298   
  299            // log the exception
  300            if (cause != null)
  301            {
  302               // if the cause is an EJBException unwrap it for logging
  303               if ((cause instanceof EJBException) &&
  304                     (((EJBException) cause).getCausedByException() != null))
  305               {
  306                  cause = ((EJBException) cause).getCausedByException();
  307               }
  308               log.error(exceptionType + " in method: " + invocation.getMethod()
  309                  + ", causedBy:", cause);
  310            }
  311            else
  312            {
  313               log.error(exceptionType + " in method: " + invocation.getMethod(), e);
  314            }
  315            return (Exception)e;
  316         }
  317         if (e instanceof NoSuchEntityException)
  318         {
  319            NoSuchEntityException noSuchEntityException =
  320                  (NoSuchEntityException) e;
  321            if (noSuchEntityException.getCausedByException() != null)
  322            {
  323               log.error("NoSuchEntityException in method: " + invocation.getMethod() + ", causedBy:",
  324                     noSuchEntityException.getCausedByException());
  325            }
  326            else
  327            {
  328               log.error("NoSuchEntityException in method: " + invocation.getMethod() + ":", noSuchEntityException);
  329            }
  330   
  331            if (isLocal)
  332            {
  333               return new NoSuchObjectLocalException(
  334                     noSuchEntityException.getMessage(),
  335                     noSuchEntityException.getCausedByException());
  336            }
  337            else
  338            {
  339               NoSuchObjectException noSuchObjectException =
  340                     new NoSuchObjectException(noSuchEntityException.getMessage());
  341               noSuchObjectException.detail = noSuchEntityException;
  342               return noSuchObjectException;
  343            }
  344         }
  345         if (e instanceof EJBException)
  346         {
  347            EJBException ejbException = (EJBException) e;
  348            if (ejbException.getCausedByException() != null)
  349            {
  350               log.error("EJBException in method: " + invocation.getMethod() + ", causedBy:",
  351                     ejbException.getCausedByException());
  352            }
  353            else
  354            {
  355               log.error("EJBException in method: " + invocation.getMethod() + ":", ejbException);
  356            }
  357   
  358            if (isLocal)
  359            {
  360               return ejbException;
  361            }
  362            else
  363            {
  364               // Remote invocation need a remote exception
  365               return new ServerException("EJBException:", ejbException);
  366            }
  367         }
  368   
  369         /* Handle SecurityExceptions specially to tranform into one of the
  370            security related ejb or rmi exceptions to allow users to identitify
  371            them more easily.
  372         */
  373         if (e instanceof SecurityException || e instanceof GeneralSecurityException)
  374         {
  375            Exception runtimeException = (Exception)e;
  376            if( log.isTraceEnabled() )
  377               log.trace("SecurityException in method: " + invocation.getMethod() + ":", runtimeException);
  378            if( isAppException(invocation, e) )
  379            {
  380               return runtimeException;
  381            }
  382            else if (isLocal)
  383            {
  384               return new AccessLocalException("SecurityException", runtimeException);
  385            }
  386            else
  387            {
  388               return new AccessException("SecurityException", runtimeException);
  389            }         
  390         }
  391   
  392         // handle unmarshalling exception which should only come if problem unmarshalling
  393         // invocation payload, arguments, or value on remote end.
  394         if(e instanceof JBossLazyUnmarshallingException)
  395         {
  396            RuntimeException runtimeException = (RuntimeException)e;
  397            log.error("UnmarshalException:",  e);
  398   
  399            if(isLocal)
  400            {
  401               return new EJBException("UnmarshalException", runtimeException);
  402            }
  403            else
  404            {
  405               return new MarshalException("MarshalException", runtimeException);
  406            }
  407         }
  408   
  409         // All other RuntimeException
  410         if (e instanceof RuntimeException)
  411         {
  412            RuntimeException runtimeException = (RuntimeException)e;
  413            log.error("RuntimeException in method: " + invocation.getMethod() + ":", runtimeException);
  414   
  415            if (isLocal)
  416            {
  417               return new EJBException("RuntimeException", runtimeException);
  418            }
  419            else
  420            {
  421               return new ServerException("RuntimeException", runtimeException);
  422            }
  423         }
  424         if (e instanceof Error)
  425         {
  426            log.error("Unexpected Error in method: " + invocation.getMethod(), e);
  427            if (isLocal)
  428            {
  429               String msg = formatException("Unexpected Error", e);
  430               return new EJBException(msg);
  431            }
  432            else
  433            {
  434               return new ServerError("Unexpected Error", (Error)e);
  435            }
  436         }
  437   
  438         // If we got a RemoteException for a local invocation wrap it
  439         // in an EJBException.
  440         if(isLocal && e instanceof RemoteException)
  441         {
  442            if (callLogging)
  443            {
  444               log.info("Remote Exception in method: " + invocation.getMethod(), e);
  445            }
  446            return new EJBException((RemoteException)e);
  447         }
  448   
  449         if (e instanceof Exception)
  450         {
  451            if (callLogging)
  452            {
  453               log.info("Application Exception in method: " + invocation.getMethod(), e);
  454            }
  455            return (Exception)e;
  456         }
  457         else
  458         {
  459            // The should not happen
  460            String msg = formatException("Unexpected Throwable", e);
  461            log.warn("Unexpected Throwable in method: " + invocation.getMethod(), e);
  462            if (isLocal)
  463            {
  464               return new EJBException(msg);
  465            }
  466            else
  467            {
  468               return new ServerException(msg);
  469            }
  470         }
  471      }
  472   
  473      private String formatException(String msg, Throwable t)
  474      {
  475         StringWriter sw = new StringWriter();
  476         PrintWriter pw = new PrintWriter(sw);
  477         if (msg != null)
  478            pw.println(msg);
  479         if (t != null)
  480         {
  481            t.printStackTrace(pw);
  482         } // end of if ()
  483         return sw.toString();
  484      }
  485   
  486   }

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