You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by dj...@apache.org on 2012/09/05 23:49:33 UTC

svn commit: r1381407 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager: AbstractComponentManager.java ComponentFactoryImpl.java DependencyManager.java ImmediateComponentManager.java

Author: djencks
Date: Wed Sep  5 21:49:33 2012
New Revision: 1381407

URL: http://svn.apache.org/viewvc?rev=1381407&view=rev
Log:
FELIX-3645 add logging and fix numerous bugs.

Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.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

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1381407&r1=1381406&r2=1381407&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Wed Sep  5 21:49:33 2012
@@ -211,6 +211,7 @@ public abstract class AbstractComponentM
                 b.append( "  " ).append( i.next() ).append( "\n" );
             }
             log( LogService.LOG_ERROR, b.toString(), null );
+            dumpThreads();
             throw e;
         }
     }
@@ -223,6 +224,7 @@ public abstract class AbstractComponentM
         {
             if (!m_stateLock.tryWriteLock( m_timeout ) )
             {
+                lockingActivity.add( "escalateLock failure from: " +  source + " readLocks: " + m_stateLock.getReadHoldCount() + " writeLocks: " + m_stateLock.getWriteHoldCount() + " thread: " + Thread.currentThread() + " time: " + System.currentTimeMillis() + " Could not obtain write lock.");
                 throw new IllegalStateException( "Could not obtain lock" );
             }
             lockingThread = Thread.currentThread();
@@ -263,7 +265,14 @@ public abstract class AbstractComponentM
         ThreadInfo[] infos = threadMXBean.dumpAllThreads( threadMXBean.isObjectMonitorUsageSupported(), threadMXBean.isSynchronizerUsageSupported() );
         for ( int i = 0; i < infos.length; i++ )
         {
-            b.append( infos[i] ).append( "\n\n" );
+            ThreadInfo ti = infos[i];
+            b.append( "\n\nThreadId: " ).append( ti.getThreadId() ).append( " : name: " ).append( ti.getThreadName() ).append( " State: " ).append( ti.getThreadState() );
+            b.append( "\n  LockInfo: " ).append( ti.getLockInfo() ).append( " LockOwnerId: " ).append( ti.getLockOwnerId() ).append( " LockOwnerName: ").append( ti.getLockOwnerName() );
+            StackTraceElement[] stackTrace = ti.getStackTrace();
+            for (int j = 0; j < stackTrace.length; j++ )
+            {
+                b.append( "\n  " ).append( stackTrace[j] );
+            }
         }
         log( LogService.LOG_ERROR, b.toString(), null );
     }
@@ -729,11 +738,12 @@ public abstract class AbstractComponentM
         }
     }
 
-    protected final boolean collectDependencies()
+    protected boolean collectDependencies()
     {
         Map old = ( Map ) m_dependencies_map.get();
         if ( old != null)
         {
+            log( LogService.LOG_DEBUG, "dependency map already present, do not collect dependencies", null );
             return false;
         }
         Class implementationObjectClass = null;
@@ -757,17 +767,26 @@ public abstract class AbstractComponentM
             {
                 //not actually satisfied any longer
                 returnServices( newDeps );
+                log( LogService.LOG_DEBUG, "Could not get dependency for dependency manager: {0}",
+                        new Object[] {dependencyManager}, null );
                 return false;
             }
         }
-        if ( !m_dependencies_map.compareAndSet( old, newDeps ))
+        if ( !setDependencyMap( old, newDeps ) )
         {
             returnServices(newDeps);
+            log( LogService.LOG_DEBUG, "Another thread set the dependency map already present, do not keep collected dependencies", null );
             return false;
         }
+        log( LogService.LOG_DEBUG, "This thread collected dependencies", null );
         return true;
     }
 
+    protected boolean setDependencyMap( Map old, Map newDeps )
+    {
+        return m_dependencies_map.compareAndSet( old, newDeps );
+    }
+
     private void returnServices( Map deps )
     {
          for (Iterator it = deps.values().iterator(); it.hasNext(); )
@@ -1299,6 +1318,7 @@ public abstract class AbstractComponentM
                 {
                     acm.deleteComponent( reason );
                     acm.deactivateDependencyManagers();
+                    acm.m_dependencies_map.set( null );
                 }
                 finally
                 {
@@ -1457,8 +1477,10 @@ public abstract class AbstractComponentM
             // 4. Call the activate method, if present
             if ( ( acm.isImmediate() || acm.getComponentMetadata().isFactory() ) )
             {
+                //don't collect dependencies for a factory component.
                  if ( !acm.collectDependencies() )
                  {
+                     acm.log( LogService.LOG_DEBUG, "Not all dependencies collected, cannot create object", null );
                      return false;
                  }
                 acm.escalateLock( "AbstractComponentManager.Unsatisifed.activate.1" );
@@ -1851,6 +1873,8 @@ public abstract class AbstractComponentM
     {
         Object get();
 
+        void set(Object o);
+
         boolean compareAndSet(Object expected, Object replacement);
 
     }
@@ -1864,6 +1888,11 @@ public abstract class AbstractComponentM
             return ref.get();
         }
 
+        public void set(Object o)
+        {
+            ref.set( o );
+        }
+
         public boolean compareAndSet(Object expected, Object replacement)
         {
             return ref.compareAndSet( expected, replacement );
@@ -1879,6 +1908,11 @@ public abstract class AbstractComponentM
             return ref.get();
         }
 
+        public void set(Object o)
+         {
+             ref.set( o );
+         }
+
         public boolean compareAndSet(Object expected, Object replacement)
         {
             return ref.commit( expected, replacement );

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=1381407&r1=1381406&r2=1381407&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java Wed Sep  5 21:49:33 2012
@@ -19,7 +19,9 @@
 package org.apache.felix.scr.impl.manager;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
@@ -91,6 +93,8 @@ public class ComponentFactoryImpl extend
     public ComponentInstance newInstance( Dictionary dictionary )
     {
         final ImmediateComponentManager cm = createComponentManager();
+        log( LogService.LOG_DEBUG, "Creating new instance from component factory {0} with configuration {1}",
+                new Object[] { getComponentMetadata().getName(), dictionary }, null );
 
         ComponentInstance instance;
         final boolean release = cm.obtainReadLock( "ComponentFactoryImpl.newInstance.1" );
@@ -255,6 +259,21 @@ public class ComponentFactoryImpl extend
         return Factory.getInstance();
     }
 
+    protected boolean collectDependencies()
+    {
+        Map old = getDependencyMap();
+        if ( old == null )
+        {
+            Map dependenciesMap = new HashMap();
+            for (Iterator i = getDependencyManagers(); i.hasNext(); )
+            {
+                dependenciesMap.put( i.next(), Collections.EMPTY_MAP );
+            }
+            setDependencyMap( old, dependenciesMap );
+        }
+        return true;
+    }
+
     //---------- Component interface
 
 

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=1381407&r1=1381406&r2=1381407&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 Wed Sep  5 21:49:33 2012
@@ -298,6 +298,10 @@ public class DependencyManager implement
             boolean handled = m_componentManager.activateInternal();
             if (!handled)
             {
+                m_componentManager.log( LogService.LOG_DEBUG,
+                    "Dependency Manager: Service {0} activation did not occur on this thread", new Object[]
+                        { m_dependencyMetadata.getName() }, null );
+
                 Map dependenciesMap = m_componentManager.getDependencyMap();
                 if (dependenciesMap  != null) {
                     //someone else has managed to activate
@@ -311,11 +315,17 @@ public class DependencyManager implement
             }
             if (handled)
             {
+                m_componentManager.log( LogService.LOG_DEBUG,
+                    "Dependency Manager: Service {0} activation on other thread bound service reference {1}", new Object[]
+                        { m_dependencyMetadata.getName(), reference }, null );
                 return;
             }
             //release our read lock and wait for activation to complete
             m_componentManager.escalateLock( "DependencyManager.serviceAdded.nothandled.1" );
             m_componentManager.deescalateLock( "DependencyManager.serviceAdded.nothandled.2" );
+            m_componentManager.log( LogService.LOG_DEBUG,
+                    "Dependency Manager: Service {0} activation on other thread: after releasing lock, component instance is: {1}", new Object[]
+                    {m_dependencyMetadata.getName(), m_componentManager.getInstance()}, null );
         }
 
         // otherwise check whether the component is in a state to handle the event
@@ -451,13 +461,16 @@ public class DependencyManager implement
 
                     if ( ref == null )
                     {
-                        m_componentManager
-                            .log(
-                                LogService.LOG_DEBUG,
-                                "Dependency Manager: Deactivating component due to mandatory dependency on {0}/{1} not satisfied",
-                                new Object[]
-                                    { m_dependencyMetadata.getName(), m_dependencyMetadata.getInterface() }, null );
-                        m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE );
+                        if ( !m_dependencyMetadata.isOptional() )
+                        {
+                            m_componentManager
+                                .log(
+                                        LogService.LOG_DEBUG,
+                                        "Dependency Manager: Deactivating component due to mandatory dependency on {0}/{1} not satisfied",
+                                        new Object[]
+                                                {m_dependencyMetadata.getName(), m_dependencyMetadata.getInterface()}, null );
+                            m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE );
+                        }
                     }
                     else
                     {
@@ -832,7 +845,12 @@ public class DependencyManager implement
      */
     private AbstractComponentManager.RefPair getBoundService( ServiceReference serviceReference )
     {
-        return ( AbstractComponentManager.RefPair ) (( Map ) m_componentManager.getDependencyMap().get( this )).get(serviceReference);
+        Map dependencyMap = m_componentManager.getDependencyMap();
+        if (dependencyMap == null)
+        {
+            return null;
+        }
+        return ( AbstractComponentManager.RefPair ) (( Map ) dependencyMap.get( this )).get(serviceReference);
     }
 
 
@@ -882,7 +900,7 @@ public class DependencyManager implement
             else
             {
                 refPair = new AbstractComponentManager.RefPair( serviceReference,  serviceObject );
-                ((Map)m_componentManager.getDependencyMap().get( this )) .put( serviceReference, refPair );
+                ((Map)m_componentManager.getDependencyMap().get( this )).put( serviceReference, refPair );
             }
         }
 
@@ -898,26 +916,30 @@ public class DependencyManager implement
     void ungetService( ServiceReference serviceReference )
     {
         // check we really have this service, do nothing if not
-        AbstractComponentManager.RefPair refPair  = ( AbstractComponentManager.RefPair ) ((Map )m_componentManager.getDependencyMap().get( this )).remove( serviceReference );
-        if ( refPair != null && refPair.getServiceObject() != null )
+        Map dependencyMap = m_componentManager.getDependencyMap();
+        if ( dependencyMap != null )
         {
-            BundleComponentActivator activator = m_componentManager.getActivator();
-            if ( activator != null )
+            AbstractComponentManager.RefPair refPair  = ( AbstractComponentManager.RefPair ) ((Map ) dependencyMap.get( this )).remove( serviceReference );
+            if ( refPair != null && refPair.getServiceObject() != null )
             {
-                BundleContext bundleContext = activator.getBundleContext();
-                if ( bundleContext != null )
+                BundleComponentActivator activator = m_componentManager.getActivator();
+                if ( activator != null )
                 {
-                    try
+                    BundleContext bundleContext = activator.getBundleContext();
+                    if ( bundleContext != null )
                     {
-                        bundleContext.ungetService( serviceReference );
-                    }
-                    catch ( IllegalStateException e )
-                    {
-                        m_componentManager.log( LogService.LOG_INFO,
-                            "For dependency {0}, trying to unget ServiceReference {1} on invalid bundle context {2}",
-                            new Object[]
-                                { m_dependencyMetadata.getName(), serviceReference.getProperty( Constants.SERVICE_ID ),
-                                    serviceReference }, null );
+                        try
+                        {
+                            bundleContext.ungetService( serviceReference );
+                        }
+                        catch ( IllegalStateException e )
+                        {
+                            m_componentManager.log( LogService.LOG_INFO,
+                                "For dependency {0}, trying to unget ServiceReference {1} on invalid bundle context {2}",
+                                new Object[]
+                                    { m_dependencyMetadata.getName(), serviceReference.getProperty( Constants.SERVICE_ID ),
+                                        serviceReference }, null );
+                        }
                     }
                 }
             }
@@ -938,7 +960,7 @@ public class DependencyManager implement
 
     /**
      * Returns <code>true</code> if this dependency manager is satisfied, that
-     * is if eithern the dependency is optional or the number of services
+     * is if either the dependency is optional or the number of services
      * registered in the framework and available to this dependency manager is
      * not zero.
      */
@@ -1041,13 +1063,16 @@ public class DependencyManager implement
         {
             // bind best matching service
             ServiceReference ref = getFrameworkServiceReference();
-            AbstractComponentManager.RefPair refPair = m_bind.getServiceObject( ref, m_componentManager.getActivator().getBundleContext() );
-            // success is if we have the minimal required number of services bound
-            if ( refPair != null )
-            {
-                result.put( ref, refPair );
-                // of course, we have success if the service is bound
-                success = true;
+            if ( ref != null )
+            {
+                AbstractComponentManager.RefPair refPair = m_bind.getServiceObject( ref, m_componentManager.getActivator().getBundleContext() );
+                // success is if we have the minimal required number of services bound
+                if ( refPair != null )
+                {
+                    result.put( ref, refPair );
+                    // of course, we have success if the service is bound
+                    success = true;
+                }
             }
         }
 
@@ -1222,8 +1247,8 @@ public class DependencyManager implement
         // null. This is valid for both immediate and delayed components
         if ( m_componentInstance != null )
         {
-            Object serviceObject = ((Map)m_componentManager.getDependencyMap().get( this )).get( ref );
-            MethodResult methodResult = m_updated.invoke( m_componentInstance, new Object[] {ref, serviceObject}, MethodResult.VOID );
+            AbstractComponentManager.RefPair refPair = ( AbstractComponentManager.RefPair ) ((Map )m_componentManager.getDependencyMap().get( this )).get( ref );
+            MethodResult methodResult = m_updated.invoke( m_componentInstance, refPair, MethodResult.VOID );
             if ( methodResult != null)
             {
                 m_componentManager.setServiceProperties( methodResult );
@@ -1378,45 +1403,51 @@ public class DependencyManager implement
         // do nothing if target filter does not change
         if ( ( m_target == null && target == null ) || ( m_target != null && m_target.equals( target ) ) )
         {
+            m_componentManager.log( LogService.LOG_DEBUG, "No change in target property for dependency {0}", new Object[]
+                { m_dependencyMetadata.getName() }, null );
             return;
         }
 
         m_target = target;
         if ( target != null )
         {
+            m_componentManager.log( LogService.LOG_DEBUG, "Setting target property for dependency {0} to {1}", new Object[]
+                { m_dependencyMetadata.getName(), target }, null );
             try
             {
                 m_targetFilter = m_componentManager.getActivator().getBundleContext().createFilter( target );
             }
             catch ( InvalidSyntaxException ise )
             {
+                m_componentManager.log( LogService.LOG_ERROR, "Invalid syntax in target property for dependency {0} to {1}", new Object[]
+                    { m_dependencyMetadata.getName(), target }, null );
                 // log
                 m_targetFilter = null;
             }
         }
         else
         {
+            m_componentManager.log( LogService.LOG_DEBUG, "Clearing target property for dependency {0}", new Object[]
+                { m_dependencyMetadata.getName() }, null );
             m_targetFilter = null;
         }
 
-        if ( m_componentManager.getDependencyMap() == null)
+        if ( m_componentManager.getDependencyMap() != null )
         {
-            //component is inactive, no bindings to change.
-            return;
-        }
-        //component is active, we need to check what might have changed.
-        // check for services to be removed
-        if ( m_targetFilter != null )
-        {
-            ServiceReference[] refs = getBoundServiceReferences();
-            if ( refs != null )
+            //component is active, we need to check what might have changed.
+            // check for services to be removed
+            if ( m_targetFilter != null )
             {
-                for ( int i = 0; i < refs.length; i++ )
+                ServiceReference[] refs = getBoundServiceReferences();
+                if ( refs != null )
                 {
-                    if ( !m_targetFilter.match( refs[i] ) )
+                    for ( int i = 0; i < refs.length; i++ )
                     {
-                        // might want to do this asynchronously ??
-                        serviceRemoved( refs[i] );
+                        if ( !m_targetFilter.match( refs[i] ) )
+                        {
+                            // might want to do this asynchronously ??
+                            serviceRemoved( refs[i] );
+                        }
                     }
                 }
             }
@@ -1427,12 +1458,15 @@ public class DependencyManager implement
         ServiceReference[] refs = getFrameworkServiceReferences();
         if ( refs != null )
         {
-            for ( int i = 0; i < refs.length; i++ )
+            if ( m_componentManager.getDependencyMap() != null )
             {
-                if ( getBoundService( refs[i] ) == null )
+                for ( int i = 0; i < refs.length; i++ )
                 {
-                    // might want to do this asynchronously ??
-                    serviceAdded( refs[i] );
+                    if ( getBoundService( refs[i] ) == null )
+                    {
+                        // might want to do this asynchronously ??
+                        serviceAdded( refs[i] );
+                    }
                 }
             }
             m_size = refs.length;

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=1381407&r1=1381406&r2=1381407&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 Wed Sep  5 21:49:33 2012
@@ -472,6 +472,7 @@ public class ImmediateComponentManager e
         if ( getState() == STATE_UNSATISFIED && configuration != null
                 && !getComponentMetadata().isConfigurationIgnored() )
         {
+            log( LogService.LOG_DEBUG, "Attempting to activate unsatisfied component", null );
             activateInternal();
             return;
         }
@@ -619,6 +620,14 @@ public class ImmediateComponentManager e
         {
             if ( m_useCount == 0 )
             {
+                if ( !collectDependencies() )
+                {
+                    log(
+                            LogService.LOG_INFO,
+                            "getService did not win collecting dependencies, try creating object anyway.",
+                            null );
+
+                }
                 escalateLock( "ImmediateComponentManager.getService.1" );
                 try
                 {