You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2010/08/05 15:20:33 UTC

svn commit: r982605 - in /felix/trunk/scr/src: main/java/org/apache/felix/scr/impl/helper/ main/java/org/apache/felix/scr/impl/manager/ test/java/org/apache/felix/scr/impl/helper/

Author: fmeschbe
Date: Thu Aug  5 13:20:32 2010
New Revision: 982605

URL: http://svn.apache.org/viewvc?rev=982605&view=rev
Log:
FELIX-2521 Support separation between "no method to be called" and "method execution failure" situations to handle according specification:
  - activate method failure is logged and must cause activation failure
  - deactivate method failure is just logged
  - modified method failure is just logged
  - bind method failure is just logged
  - unbind method failure is just logged

Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java?rev=982605&r1=982604&r2=982605&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java Thu Aug  5 13:20:32 2010
@@ -24,10 +24,18 @@ import java.lang.reflect.Method;
 
 import org.apache.felix.scr.impl.manager.AbstractComponentManager;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.log.LogService;
 
 
 public class ActivateMethod extends BaseMethod
 {
+
+    Class[] ACTIVATE_TYPES_DS11 =
+        { COMPONENT_CONTEXT_CLASS, BUNDLE_CONTEXT_CLASS, MAP_CLASS };
+    Class[] ACTIVATE_TYPES_DS10 =
+        { COMPONENT_CONTEXT_CLASS };
+
+
     public ActivateMethod( final AbstractComponentManager componentManager, final String methodName,
         final boolean methodRequired, final Class componentClass )
     {
@@ -133,9 +141,9 @@ public class ActivateMethod extends Base
     }
 
 
-    public boolean invoke( Object componentInstance, Object rawParameter )
+    public boolean invoke( Object componentInstance, Object rawParameter, final boolean methodCallFailureResult )
     {
-        return methodExists() && super.invoke( componentInstance, rawParameter );
+        return methodExists() && super.invoke( componentInstance, rawParameter, methodCallFailureResult );
     }
 
 
@@ -173,9 +181,9 @@ public class ActivateMethod extends Base
             }
             catch ( SuitableMethodNotAccessibleException thrown )
             {
+                getComponentManager().log( LogService.LOG_DEBUG, "SuitableMethodNotAccessible", thrown );
                 ex = thrown;
             }
-
         }
 
         // rethrow if we looked for all method signatures and only found
@@ -223,14 +231,7 @@ public class ActivateMethod extends Base
 
     protected Class[] getAcceptedParameterTypes()
     {
-        if ( isDS11() )
-        {
-            return new Class[]
-                { COMPONENT_CONTEXT_CLASS, BUNDLE_CONTEXT_CLASS, MAP_CLASS };
-        }
-
-        return new Class[]
-            { COMPONENT_CONTEXT_CLASS };
+        return isDS11() ? ACTIVATE_TYPES_DS11 : ACTIVATE_TYPES_DS10;
     }
 
 

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java?rev=982605&r1=982604&r2=982605&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java Thu Aug  5 13:20:32 2010
@@ -22,6 +22,7 @@ package org.apache.felix.scr.impl.helper
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.Arrays;
 import java.util.Map;
 
 import org.apache.felix.scr.impl.manager.AbstractComponentManager;
@@ -49,7 +50,7 @@ abstract class BaseMethod
     private final String m_methodName;
     private final Class m_componentClass;
 
-    private Method m_method = null;
+    private Method m_method;
 
     private final boolean m_methodRequired;
 
@@ -112,10 +113,15 @@ abstract class BaseMethod
         if ( method != null )
         {
             m_state = Resolved.INSTANCE;
+            getComponentManager().log( LogService.LOG_DEBUG, "Found {0} method: {1}", new Object[]
+                { getMethodNamePrefix(), method }, null );
         }
         else if ( m_methodRequired )
         {
             m_state = NotFound.INSTANCE;
+            getComponentManager().log( LogService.LOG_DEBUG, "{0} method [{1}] not found, will not invoke",
+                new Object[]
+                    { getMethodNamePrefix(), getMethodName() }, null );
         }
         else
         {
@@ -161,6 +167,12 @@ abstract class BaseMethod
         for ( Class theClass = targetClass; theClass != null; )
         {
 
+            if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            {
+                getComponentManager().log( LogService.LOG_DEBUG,
+                    "Locating method " + getMethodName() + " in class " + theClass.getName(), null );
+            }
+
             try
             {
                 Method method = doFindMethod( theClass, acceptPrivate, acceptPackage );
@@ -205,6 +217,7 @@ abstract class BaseMethod
 
 
     private boolean invokeMethod( final Object componentInstance, final Object rawParameter )
+        throws InvocationTargetException
     {
         try
         {
@@ -235,20 +248,11 @@ abstract class BaseMethod
         }
         catch ( InvocationTargetException ex )
         {
-            // 112.5.7 If a bind method throws an exception, SCR must log an
-            // error message containing the exception [...]
-            getComponentManager().log( LogService.LOG_ERROR, "The {0} method has thrown an exception", new Object[]
-                { getMethodName() }, ex.getCause() );
-            return false;
+            throw ex;
         }
         catch ( Throwable t )
         {
-            // anything else went wrong, log the message and fail the invocation
-            getComponentManager().log( LogService.LOG_ERROR, "The {0} method could not be called", new Object[]
-                { getMethodName() }, t );
-
-            // method invocation threw, so it was a failure
-            return false;
+            throw new InvocationTargetException( t );
         }
 
         // assume success (also if the mehotd is not available or accessible)
@@ -319,6 +323,12 @@ abstract class BaseMethod
         {
             // thrown if no method is declared with the given name and
             // parameters
+            if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            {
+                String argList = ( parameterTypes != null ) ? Arrays.asList( parameterTypes ).toString() : "";
+                getComponentManager().log( LogService.LOG_DEBUG, "Declared Method {0}.{1}({2}) not found", new Object[]
+                    { clazz.getName(), name, argList }, null );
+            }
         }
         catch ( NoClassDefFoundError cdfe )
         {
@@ -437,9 +447,37 @@ abstract class BaseMethod
 
     //---------- State management  ------------------------------------
 
-    public boolean invoke( final Object componentInstance, final Object rawParameter )
+    /**
+     * Calls the declared method on the given component with the provided
+     * method call arguments.
+     *
+     * @param componentInstance The component instance on which to call the
+     *      method
+     * @param rawParameter The parameter container providing the actual
+     *      parameters to provide to the called method
+     * @param methodCallFailureResult The result to return from this method if
+     *      calling the method resulted in an exception.
+     *
+     * @return <code>true</code> if the method was called successfully or the
+     *      method was not found and was not required. <code>false</code> if
+     *      the method was not found but required.
+     *      <code>methodCallFailureResult</code> is returned if the method was
+     *      found and called, but the method threw an exception.
+     */
+    public boolean invoke( final Object componentInstance, final Object rawParameter,
+        final boolean methodCallFailureResult )
     {
-        return m_state.invoke( this, componentInstance, rawParameter );
+        try
+        {
+            return m_state.invoke( this, componentInstance, rawParameter );
+        }
+        catch ( InvocationTargetException ite )
+        {
+            getComponentManager().log( LogService.LOG_ERROR, "The {0} method has thrown an exception", new Object[]
+                { getMethodName() }, ite.getCause() );
+        }
+
+        return methodCallFailureResult;
     }
 
 
@@ -451,7 +489,8 @@ abstract class BaseMethod
     private static interface State
     {
 
-        boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter );
+        boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter )
+            throws InvocationTargetException;
 
 
         boolean methodExists( final BaseMethod baseMethod );
@@ -485,24 +524,25 @@ abstract class BaseMethod
             baseMethod.getComponentManager().log( LogService.LOG_DEBUG, "getting {0}: {1}", new Object[]
                 { baseMethod.getMethodNamePrefix(), baseMethod.getMethodName() }, null );
 
-            // resolve the method
-            Method method;
-            try
-            {
-                method = baseMethod.findMethod();
-            }
-            catch ( InvocationTargetException ex )
-            {
-                method = null;
-                baseMethod.getComponentManager().log( LogService.LOG_WARNING, "{0} cannot be found", new Object[]
-                    { baseMethod.getMethodName() }, ex.getTargetException() );
-            }
+                // resolve the method
+                Method method;
+                try
+                {
+                    method = baseMethod.findMethod();
+                }
+                catch ( InvocationTargetException ex )
+                {
+                    method = null;
+                    baseMethod.getComponentManager().log( LogService.LOG_WARNING, "{0} cannot be found", new Object[]
+                        { baseMethod.getMethodName() }, ex.getTargetException() );
+                }
 
-            baseMethod.setMethod( method );
-        }
+                baseMethod.setMethod( method );
+            }
 
 
         public boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter )
+            throws InvocationTargetException
         {
             resolve( baseMethod );
             return baseMethod.getState().invoke( baseMethod, componentInstance, rawParameter );
@@ -544,6 +584,7 @@ abstract class BaseMethod
 
 
         public boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter )
+            throws InvocationTargetException
         {
             baseMethod.getComponentManager().log( LogService.LOG_DEBUG, "invoking {0}: {1}", new Object[]
                 { baseMethod.getMethodNamePrefix(), baseMethod.getMethodName() }, null );

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=982605&r1=982604&r2=982605&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Thu Aug  5 13:20:32 2010
@@ -1025,22 +1025,20 @@ public class DependencyManager implement
         // null. This is valid for both immediate and delayed components
         if( m_componentInstance != null )
         {
-            return m_bind.invoke(
-                m_componentInstance,
-                new BindMethod.Service()
+            return m_bind.invoke( m_componentInstance, new BindMethod.Service()
+            {
+                public ServiceReference getReference()
                 {
-                    public ServiceReference getReference()
-                    {
-                        bindService( ref );
-                        return ref;
-                    }
+                    bindService( ref );
+                    return ref;
+                }
 
-                    public Object getInstance()
-                    {
-                        return getService( ref );
-                    }
+
+                public Object getInstance()
+                {
+                    return getService( ref );
                 }
-            );
+            }, true );
         }
         else if ( !m_componentManager.getComponentMetadata().isImmediate() )
         {
@@ -1099,7 +1097,7 @@ public class DependencyManager implement
                 {
                     return getService( ref );
                 }
-            } );
+            }, true );
         }
         else
         {
@@ -1128,21 +1126,19 @@ public class DependencyManager implement
         // null. This is valid for both immediate and delayed components
         if ( m_componentInstance != null )
         {
-            m_unbind.invoke(
-                m_componentInstance,
-                new BindMethod.Service()
+            m_unbind.invoke( m_componentInstance, new BindMethod.Service()
+            {
+                public ServiceReference getReference()
                 {
-                    public ServiceReference getReference()
-                    {
-                        return ref;
-                    }
+                    return ref;
+                }
 
-                    public Object getInstance()
-                    {
-                        return getService( ref );
-                    }
+
+                public Object getInstance()
+                {
+                    return getService( ref );
                 }
-            );
+            }, true );
         }
         else
         {

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java?rev=982605&r1=982604&r2=982605&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java Thu Aug  5 13:20:32 2010
@@ -224,7 +224,7 @@ public class ImmediateComponentManager e
 
         // 4. Call the activate method, if present
         if ( !m_activateMethod.invoke( implementationObject,
-            new ActivateMethod.ActivatorParameter( componentContext, 1 ) ) )
+            new ActivateMethod.ActivatorParameter( componentContext, 1 ), false ) )
         {
             // 112.5.8 If the activate method throws an exception, SCR must log an error message
             // containing the exception with the Log Service and activation fails
@@ -258,7 +258,7 @@ public class ImmediateComponentManager e
         // method throws an exception, SCR must log an error message containing the
         // exception with the Log Service and continue) has already been logged
         m_deactivateMethod.invoke( implementationObject, new ActivateMethod.ActivatorParameter( componentContext,
-            reason ) );
+            reason ), true );
 
         // 2. Unbind any bound services
         Iterator it = getDependencyManagers();
@@ -415,6 +415,7 @@ public class ImmediateComponentManager e
         }
         else if ( !modify() )
         {
+            // SCR 112.7.1 - deactivate if configuration is deleted or no modified method declared
             log( LogService.LOG_DEBUG, "Deactivating and Activating to reconfigure from configuration", null );
             int reason = ( configuration == null ) ? ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED
                 : ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_MODIFIED;
@@ -467,10 +468,11 @@ public class ImmediateComponentManager e
         // invariant: modify method existing and no static bound service changes
 
         // 4. call method (nothing to do when failed, since it has already been logged)
-        if ( !m_modifyMethod.invoke( getInstance(), new ActivateMethod.ActivatorParameter( m_componentContext, -1 ) ) )
+        if ( !m_modifyMethod.invoke( getInstance(), new ActivateMethod.ActivatorParameter( m_componentContext, -1 ),
+            true ) )
         {
             // log an error if the declared method cannot be found
-            log( LogService.LOG_ERROR, "Declared modify method '{0}' cannot be found, configuring by reactivation",
+            log( LogService.LOG_ERROR, "Declared modify method ''{0}'' cannot be found, configuring by reactivation",
                 new Object[]
                     { getComponentMetadata().getModified() }, null );
             return false;

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java?rev=982605&r1=982604&r2=982605&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java Thu Aug  5 13:20:32 2010
@@ -230,7 +230,7 @@ public class ActivateMethodTest extends 
         };
         ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata );
         ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass() );
-        am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ) );
+        am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), false );
         Method m = get(am, "m_method");
         assertNotNull( m );
         assertEquals( methodName, m.getName() );
@@ -258,7 +258,7 @@ public class ActivateMethodTest extends 
         };
         ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata );
         ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass() );
-        am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ) );
+        am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), false );
         assertNull( get( am, "m_method" ) );
         assertNull( obj.getCalledMethod() );
     }

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java?rev=982605&r1=982604&r2=982605&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java Thu Aug  5 13:20:32 2010
@@ -441,7 +441,7 @@ public class BindMethodTest extends Test
         ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata );
         BindMethod bm = new BindMethod( icm, methodName, component.getClass(), "reference",
             FakeService.class.getName() );
-        bm.invoke( component, m_service );
+        bm.invoke( component, m_service, true );
         assertEquals( expectCallPerformed, component.callPerformed );
     }
 }