You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by tj...@apache.org on 2017/04/20 13:28:49 UTC

svn commit: r1792053 - in /felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods: ActivateMethod.java BaseMethod.java BindMethod.java

Author: tjwatson
Date: Thu Apr 20 13:28:49 2017
New Revision: 1792053

URL: http://svn.apache.org/viewvc?rev=1792053&view=rev
Log:
FELIX-5615 - Global lock in BaseMethod.NotResolved::resolve method causes deadlock

Porting the fix to the R7 SCR implementation

Modified:
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java

Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java?rev=1792053&r1=1792052&r2=1792053&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java Thu Apr 20 13:28:49 2017
@@ -38,7 +38,7 @@ import org.apache.felix.scr.impl.metadat
 import org.osgi.service.log.LogService;
 
 
-public class ActivateMethod extends BaseMethod<ActivatorParameter> implements LifecycleMethod
+public class ActivateMethod extends BaseMethod<ActivatorParameter, Object> implements LifecycleMethod
 {
 
     protected final boolean m_supportsInterfaces;
@@ -56,7 +56,7 @@ public class ActivateMethod extends Base
 
 
     @Override
-    protected Method doFindMethod( Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
+    protected MethodInfo<Object> doFindMethod( Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
         throws SuitableMethodNotAccessibleException, InvocationTargetException
     {
 
@@ -69,7 +69,7 @@ public class ActivateMethod extends Base
                 { ClassUtils.COMPONENT_CONTEXT_CLASS }, acceptPrivate, acceptPackage, logger );
             if ( method != null )
             {
-                return method;
+                return new MethodInfo<Object>(method);
             }
         }
         catch ( SuitableMethodNotAccessibleException thrown )
@@ -91,7 +91,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -99,7 +99,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -107,7 +107,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -115,7 +115,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -123,7 +123,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -149,7 +149,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -159,7 +159,7 @@ public class ActivateMethod extends Base
                 {
                     if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                     {
-                        return m;
+                        return new MethodInfo<Object>(m);
                     }
                     suitableMethodNotAccessible = true;
                 }
@@ -175,6 +175,11 @@ public class ActivateMethod extends Base
         return null;
     }
 
+    @Override
+    protected void setTypes(Object types)
+    {
+        // Don't care about types
+    }
 
     boolean isDeactivate()
     {

Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java?rev=1792053&r1=1792052&r2=1792053&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java Thu Apr 20 13:28:49 2017
@@ -38,7 +38,7 @@ import org.osgi.service.log.LogService;
 /**
  * Component method to be invoked on service (un)binding.
  */
-public abstract class BaseMethod<P extends BaseParameter>
+public abstract class BaseMethod<P extends BaseParameter, T>
 {
 
     private final DSVersion dsVersion;
@@ -105,16 +105,18 @@ public abstract class BaseMethod<P exten
         return m_componentClass;
     }
 
+    protected abstract void setTypes(T types);
 
-    void setMethod( Method method, SimpleLogger logger )
+    synchronized void setMethod(MethodInfo<T> methodInfo, SimpleLogger logger)
     {
-        this.m_method = method;
+        this.m_method = methodInfo == null ? null : methodInfo.getMethod();
 
-        if ( method != null )
+        if (m_method != null)
         {
+            setTypes(methodInfo.getTypes());
             m_state = Resolved.INSTANCE;
             logger.log( LogService.LOG_DEBUG, "Found {0} method: {1}", new Object[]
-                    { getMethodNamePrefix(), method }, null );
+                    { getMethodNamePrefix(), m_method }, null);
         }
         else if ( m_methodRequired )
         {
@@ -151,7 +153,7 @@ public abstract class BaseMethod<P exten
      *      trying to find the requested method.
      * @param logger
      */
-    private Method findMethod( SimpleLogger logger ) throws InvocationTargetException
+    private MethodInfo<T> findMethod(SimpleLogger logger) throws InvocationTargetException
     {
         boolean acceptPrivate = getDSVersion().isDS11();
         boolean acceptPackage = getDSVersion().isDS11();
@@ -172,7 +174,9 @@ public abstract class BaseMethod<P exten
 
             try
             {
-                Method method = doFindMethod( theClass, acceptPrivate, acceptPackage, logger );
+                MethodInfo<T> method = doFindMethod(theClass, acceptPrivate,
+                    acceptPackage,
+                    logger);
                 if ( method != null )
                 {
                     return method;
@@ -209,7 +213,8 @@ public abstract class BaseMethod<P exten
     }
 
 
-    protected abstract Method doFindMethod( final Class<?> targetClass, final boolean acceptPrivate,
+    protected abstract MethodInfo<T> doFindMethod(final Class<?> targetClass,
+        final boolean acceptPrivate,
             final boolean acceptPackage, SimpleLogger logger ) throws SuitableMethodNotAccessibleException, InvocationTargetException;
 
 
@@ -522,14 +527,41 @@ public abstract class BaseMethod<P exten
         return m_state.methodExists( this, logger );
     }
 
+    protected static final class MethodInfo<T>
+    {
+        private final Method m_method;
+        private final T m_types;
+
+        public MethodInfo(Method m)
+        {
+            this(m, null);
+        }
+
+        public MethodInfo(Method m, T types)
+        {
+            m_method = m;
+            m_types = types;
+        }
+
+        public Method getMethod()
+        {
+            return m_method;
+        }
+
+        public T getTypes()
+        {
+            return m_types;
+        }
+    }
+
     private static interface State
     {
 
-        <P extends BaseParameter> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter )
+        <P extends BaseParameter, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter )
                 throws InvocationTargetException;
 
 
-        <P extends BaseParameter> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger );
+        <P extends BaseParameter, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger );
     }
 
     private static class NotApplicable implements State
@@ -539,14 +571,14 @@ public abstract class BaseMethod<P exten
 
 
         @Override
-        public <P extends BaseParameter> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter )
+        public <P extends BaseParameter, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter )
         {
             return MethodResult.VOID;
         }
 
 
         @Override
-        public <P extends BaseParameter> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P extends BaseParameter, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             return true;
         }
@@ -557,13 +589,13 @@ public abstract class BaseMethod<P exten
         private static final State INSTANCE = new NotResolved();
 
 
-        private synchronized <P extends BaseParameter> void resolve( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        private <P extends BaseParameter, T> void resolve( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             logger.log( LogService.LOG_DEBUG, "getting {0}: {1}", new Object[]
                     {baseMethod.getMethodNamePrefix(), baseMethod.getMethodName()}, null );
 
             // resolve the method
-            Method method = null;
+            MethodInfo<T> method = null;
             try
             {
                 method = baseMethod.findMethod( logger );
@@ -579,7 +611,7 @@ public abstract class BaseMethod<P exten
 
 
         @Override
-        public <P extends BaseParameter> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter )
+        public <P extends BaseParameter, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter )
                 throws InvocationTargetException
         {
             resolve( baseMethod, rawParameter.getLogger() );
@@ -588,7 +620,7 @@ public abstract class BaseMethod<P exten
 
 
         @Override
-        public <P extends BaseParameter> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P extends BaseParameter, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             resolve( baseMethod, logger );
             return baseMethod.getState().methodExists( baseMethod, logger );
@@ -601,7 +633,7 @@ public abstract class BaseMethod<P exten
 
 
         @Override
-        public <P extends BaseParameter> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter )
+        public <P extends BaseParameter, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter )
         {
             // 112.3.1 If the method is not found , SCR must log an error
             // message with the log service, if present, and ignore the
@@ -613,7 +645,7 @@ public abstract class BaseMethod<P exten
 
 
         @Override
-        public <P extends BaseParameter> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P extends BaseParameter, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             return false;
         }
@@ -625,7 +657,7 @@ public abstract class BaseMethod<P exten
 
 
         @Override
-        public <P extends BaseParameter> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter )
+        public <P extends BaseParameter, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter )
                 throws InvocationTargetException
         {
             return baseMethod.invokeMethod( componentInstance, rawParameter );
@@ -633,7 +665,7 @@ public abstract class BaseMethod<P exten
 
 
         @Override
-        public <P extends BaseParameter> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P extends BaseParameter, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             return true;
         }

Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java?rev=1792053&r1=1792052&r2=1792053&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java Thu Apr 20 13:28:49 2017
@@ -40,7 +40,7 @@ import org.osgi.service.log.LogService;
  * Component method to be invoked on service (un)binding.
  * @param <S>
  */
-public class BindMethod extends BaseMethod<BindParameters>
+public class BindMethod extends BaseMethod<BindParameters, List<ValueUtils.ValueType>>
 implements org.apache.felix.scr.impl.inject.ReferenceMethod
 {
     private final String m_referenceClassName;
@@ -76,7 +76,7 @@ implements org.apache.felix.scr.impl.inj
      *      trying to find the requested method.
      */
     @Override
-    protected Method doFindMethod( final Class<?> targetClass,
+    protected MethodInfo<List<ValueUtils.ValueType>> doFindMethod( final Class<?> targetClass,
             final boolean acceptPrivate,
             final boolean acceptPackage,
             final SimpleLogger logger )
@@ -112,8 +112,7 @@ implements org.apache.felix.scr.impl.inj
                 {
                     logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                 }
-                m_paramTypes = Collections.singletonList(ValueUtils.ValueType.ref_serviceReference);
-                return method;
+                return new MethodInfo<List<ValueUtils.ValueType>>(method, Collections.singletonList(ValueUtils.ValueType.ref_serviceReference));
             }
         }
         catch ( SuitableMethodNotAccessibleException ex )
@@ -133,8 +132,7 @@ implements org.apache.felix.scr.impl.inj
                     {
                         logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                     }
-                    m_paramTypes = Collections.singletonList(ValueUtils.ValueType.ref_serviceObjects);
-                    return method;
+                    return new MethodInfo<List<ValueUtils.ValueType>>(method, Collections.singletonList(ValueUtils.ValueType.ref_serviceObjects));
                 }
             }
             catch ( SuitableMethodNotAccessibleException ex )
@@ -166,8 +164,8 @@ implements org.apache.felix.scr.impl.inj
                     {
                         logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                     }
-                    m_paramTypes = Collections.singletonList(ValueUtils.ValueType.ref_serviceType);
-                    return method;
+                    return new MethodInfo<List<ValueUtils.ValueType>>(method,
+                        Collections.singletonList(ValueUtils.ValueType.ref_serviceType));
                 }
             }
             catch ( SuitableMethodNotAccessibleException ex )
@@ -185,8 +183,8 @@ implements org.apache.felix.scr.impl.inj
                     {
                         logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                     }
-                    m_paramTypes = Collections.singletonList(ValueUtils.ValueType.ref_serviceType);
-                    return method;
+                    return new MethodInfo<List<ValueUtils.ValueType>>(method,
+                        Collections.singletonList(ValueUtils.ValueType.ref_serviceType));
                 }
             }
             catch ( SuitableMethodNotAccessibleException ex )
@@ -206,8 +204,8 @@ implements org.apache.felix.scr.impl.inj
                         {
                             logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                         }
-                        m_paramTypes = Collections.singletonList(ValueUtils.ValueType.ref_map);
-                        return method;
+                        return new MethodInfo<List<ValueUtils.ValueType>>(method,
+                            Collections.singletonList(ValueUtils.ValueType.ref_map));
                     }
                 }
                 catch ( SuitableMethodNotAccessibleException ex )
@@ -233,8 +231,7 @@ implements org.apache.felix.scr.impl.inj
                         List<ValueUtils.ValueType> paramTypes = new ArrayList<ValueUtils.ValueType>(2);
                         paramTypes.add(ValueUtils.ValueType.ref_serviceType);
                         paramTypes.add(ValueUtils.ValueType.ref_map);
-                        m_paramTypes = paramTypes;
-                        return method;
+                        return new MethodInfo<List<ValueUtils.ValueType>>(method, paramTypes);
                     }
                 }
                 catch ( SuitableMethodNotAccessibleException ex )
@@ -256,8 +253,8 @@ implements org.apache.felix.scr.impl.inj
                         List<ValueUtils.ValueType> paramTypes = new ArrayList<ValueUtils.ValueType>(2);
                         paramTypes.add(ValueUtils.ValueType.ref_serviceType);
                         paramTypes.add(ValueUtils.ValueType.ref_map);
-                        m_paramTypes = paramTypes;
-                        return method;
+                        return new MethodInfo<List<ValueUtils.ValueType>>(method,
+                            paramTypes);
                     }
                 }
                 catch ( SuitableMethodNotAccessibleException ex )
@@ -348,8 +345,7 @@ implements org.apache.felix.scr.impl.inj
                                 {
                                     logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + m, null );
                                 }
-                                m_paramTypes = paramTypes;
-                                return m;
+                                return new MethodInfo<List<ValueUtils.ValueType>>(m, paramTypes);
                             }
                             suitableMethodNotAccessible = true;
                         }
@@ -379,6 +375,12 @@ implements org.apache.felix.scr.impl.inj
         return null;
     }
 
+    @Override
+    protected void setTypes(List<ValueUtils.ValueType> types)
+    {
+        m_paramTypes = types;
+    }
+
     /**
      * Returns a method taking a single <code>ServiceReference</code> object
      * as a parameter or <code>null</code> if no such method exists.