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 2007/08/22 17:28:38 UTC

svn commit: r568657 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr: AbstractComponentManager.java ComponentFactoryImpl.java DelayedComponentManager.java ImmediateComponentManager.java ServiceFactoryComponentManager.java

Author: fmeschbe
Date: Wed Aug 22 08:28:37 2007
New Revision: 568657

URL: http://svn.apache.org/viewvc?rev=568657&view=rev
Log:
FELIX-341 Intermittent exception during Felix shutdown

Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java?rev=568657&r1=568656&r2=568657&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java Wed Aug 22 08:28:37 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.scr;
 
+
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
@@ -27,7 +28,6 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentInstance;
@@ -61,7 +61,7 @@
     // manager for a component factory has been registered
     static final int STATE_FACTORY = 64;
 
-	// manager is current deactivating
+    // manager is current deactivating
     static final int STATE_DEACTIVATING = 128;
 
     // manager has been destroyed and may not be used anymore
@@ -82,13 +82,14 @@
     // The ServiceRegistration
     private ServiceRegistration m_serviceRegistration;
 
+
     /**
      * The constructor receives both the activator and the metadata
      *
      * @param activator
      * @param metadata
      */
-    protected AbstractComponentManager(BundleComponentActivator activator, ComponentMetadata metadata)
+    protected AbstractComponentManager( BundleComponentActivator activator, ComponentMetadata metadata )
     {
         m_activator = activator;
         m_componentMetadata = metadata;
@@ -96,9 +97,10 @@
         m_state = STATE_DISABLED;
         m_dependencyManagers = new ArrayList();
 
-        Activator.trace("Component created", m_componentMetadata);
+        Activator.trace( "Component created", m_componentMetadata );
     }
 
+
     //---------- Asynchronous frontend to state change methods ----------------
 
     /**
@@ -111,32 +113,36 @@
      * <p>
      * This method schedules the enablement for asynchronous execution.
      */
-    public final void enable() {
-        this.getActivator().schedule( new Runnable()
+    public final void enable()
+    {
+        getActivator().schedule( new Runnable()
         {
             public void run()
             {
-                AbstractComponentManager.this.enableInternal();
+                enableInternal();
             }
         } );
     }
 
+
     /**
      * Activates this component if satisfied. If any of the dependencies is
      * not met, the component is not activated and remains unsatisifed.
      * <p>
      * This method schedules the activation for asynchronous execution.
      */
-    public final void activate() {
-        this.getActivator().schedule( new Runnable()
+    public final void activate()
+    {
+        getActivator().schedule( new Runnable()
         {
             public void run()
             {
-                AbstractComponentManager.this.activateInternal();
+                activateInternal();
             }
         } );
     }
 
+
     /**
      * Reconfigures this component by deactivating and activating it. During
      * activation the new configuration data is retrieved from the Configuration
@@ -145,58 +151,65 @@
     public final void reconfigure()
     {
         Activator.trace( "Deactivating and Activating to reconfigure", m_componentMetadata );
-        this.reactivate();
+        reactivate();
     }
 
+
     /**
      * Cycles this component by deactivating it and - if still satisfied -
      * activating it again.
      * <p>
      * This method schedules the reactivation for asynchronous execution.
      */
-    public final void reactivate() {
-        this.getActivator().schedule( new Runnable()
+    public final void reactivate()
+    {
+        getActivator().schedule( new Runnable()
         {
             public void run()
             {
-                AbstractComponentManager.this.deactivateInternal();
-                Activator.trace( "Dependency Manager: RECREATING", AbstractComponentManager.this.m_componentMetadata );
-                AbstractComponentManager.this.activateInternal();
+                deactivateInternal();
+                Activator.trace( "Dependency Manager: RECREATING", m_componentMetadata );
+                activateInternal();
             }
         } );
     }
 
+
     /**
      * Deactivates the component.
      * <p>
      * This method schedules the deactivation for asynchronous execution.
      */
-    public final void deactivate() {
-        this.getActivator().schedule( new Runnable()
+    public final void deactivate()
+    {
+        getActivator().schedule( new Runnable()
         {
             public void run()
             {
-                AbstractComponentManager.this.deactivateInternal();
+                deactivateInternal();
             }
         } );
     }
 
+
     /**
      * Disables this component and - if active - first deactivates it. The
      * component may be reenabled by calling the {@link #enable()} method.
      * <p>
      * This method schedules the disablement for asynchronous execution.
      */
-    public final void disable() {
-        this.getActivator().schedule( new Runnable()
+    public final void disable()
+    {
+        getActivator().schedule( new Runnable()
         {
             public void run()
             {
-                AbstractComponentManager.this.disableInternal();
+                disableInternal();
             }
         } );
     }
 
+
     /**
      * Disposes off this component deactivating and disabling it first as
      * required. After disposing off the component, it may not be used anymore.
@@ -206,10 +219,12 @@
      * method has to actually complete before other actions like bundle stopping
      * may continue.
      */
-    public final void dispose() {
-        this.disposeInternal();
+    public final void dispose()
+    {
+        disposeInternal();
     }
 
+
     //---------- internal immediate state change methods ----------------------
     // these methods must only be called from a separate thread by calling
     // the respective asynchronous (public) method
@@ -219,56 +234,58 @@
      *
      * @return true if enabling was successful
      */
-    private void enableInternal() {
+    private void enableInternal()
+    {
 
-        if (this.getState() == STATE_DESTROYED)
+        if ( getState() == STATE_DESTROYED )
         {
             Activator.error( "Destroyed Component cannot be enabled", m_componentMetadata );
             return;
         }
-        else if (this.getState() != STATE_DISABLED)
+        else if ( getState() != STATE_DISABLED )
         {
             Activator.trace( "Component is already enabled", m_componentMetadata );
             return;
         }
 
-        Activator.trace("Enabling component", m_componentMetadata);
+        Activator.trace( "Enabling component", m_componentMetadata );
+
+        try
+        {
+            // If this component has got dependencies, create dependency managers for each one of them.
+            if ( m_componentMetadata.getDependencies().size() != 0 )
+            {
+                Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
+
+                while ( dependencyit.hasNext() )
+                {
+                    ReferenceMetadata currentdependency = ( ReferenceMetadata ) dependencyit.next();
+
+                    DependencyManager depmanager = new DependencyManager( this, currentdependency );
 
-    	try
-    	{
-	        // If this component has got dependencies, create dependency managers for each one of them.
-	        if (m_componentMetadata.getDependencies().size() != 0)
-	        {
-	            Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
-
-	            while(dependencyit.hasNext())
-	            {
-	                ReferenceMetadata currentdependency = (ReferenceMetadata)dependencyit.next();
-
-	                DependencyManager depmanager = new DependencyManager(this, currentdependency);
-
-	                m_dependencyManagers.add(depmanager);
-	            }
-	        }
+                    m_dependencyManagers.add( depmanager );
+                }
+            }
 
             // enter enabled state before trying to activate
-	        this.setState( STATE_ENABLED );
+            setState( STATE_ENABLED );
 
-            Activator.trace("Component enabled", m_componentMetadata);
+            Activator.trace( "Component enabled", m_componentMetadata );
 
             // immediately activate the compopnent, no need to schedule again
-	        this.activateInternal();
-    	}
-    	catch(Exception ex)
-    	{
-    		Activator.exception( "Failed enabling Component", m_componentMetadata, ex );
+            activateInternal();
+        }
+        catch ( Exception ex )
+        {
+            Activator.exception( "Failed enabling Component", m_componentMetadata, ex );
 
             // ensure we get back to DISABLED state
             // immediately disable, no need to schedule again
-            this.disableInternal();
-    	}
+            disableInternal();
+        }
     }
 
+
     /**
      * Activate this Instance manager.
      *
@@ -279,233 +296,260 @@
      *   4. Call the activate method, if present
      *   [5. Register provided services]
      */
-     private void activateInternal()
-     {
-         // CONCURRENCY NOTE: This method is called either by the enable()
-         //     method or by the dependency managers or the reconfigure() method
-         if ( (this.getState() & (STATE_ENABLED|STATE_UNSATISFIED)) == 0)
-         {
-             // This state can only be entered from the ENABLED (in the enable()
-             // method) or UNSATISFIED (missing references) states
-             return;
-         }
-
-         // go to the activating state
-         this.setState(STATE_ACTIVATING);
-
-         Activator.trace("Activating component", m_componentMetadata);
-
-         // Before creating the implementation object, we are going to
-         // test if all the mandatory dependencies are satisfied
-         Iterator it = m_dependencyManagers.iterator();
-         while (it.hasNext())
-         {
-             DependencyManager dm = (DependencyManager)it.next();
-             if (!dm.isValid())
-             {
-                 // at least one dependency is not satisfied
-                 Activator.trace( "Dependency not satisfied: " + dm.getName(), m_componentMetadata );
-                 this.setState(STATE_UNSATISFIED);
-                 return;
-             }
-         }
-
-         // 1. Load the component implementation class
-         // 2. Create the component instance and component context
-         // 3. Bind the target services
-         // 4. Call the activate method, if present
-         this.createComponent();
-
-         // Validation occurs before the services are provided, otherwhise the
-         // service provider's service may be called by a service requester
-         // while it is still ACTIVATING
-         this.setState(this.getSatisfiedState());
-
-         // 5. Register provided services
-         m_serviceRegistration = this.registerComponentService();
-
-         Activator.trace("Component activated", m_componentMetadata);
-     }
-
-     /**
-      * This method deactivates the manager, performing the following steps
-      *
-      * [0. Remove published services from the registry]
-      * 1. Call the deactivate() method, if present
-      * 2. Unbind any bound services
-      * 3. Release references to the component instance and component context
-     **/
-     private void deactivateInternal()
-     {
-         // CONCURRENCY NOTE: This method may be called either from application
-         // code or by the dependency managers or reconfiguration
-         if ((this.getState() & (STATE_ACTIVATING|STATE_ACTIVE|STATE_REGISTERED|STATE_FACTORY)) == 0)
-         {
-             // This state can only be entered from the ACTIVATING (if activation
-             // fails), ACTIVE, REGISTERED or FACTORY states
-             return;
-         }
-
-         // start deactivation by resetting the state
-         this.setState( STATE_DEACTIVATING );
-
-         Activator.trace("Deactivating component", m_componentMetadata);
-
-         // 0.- Remove published services from the registry
-         this.unregisterComponentService();
-
-         // 1.- Call the deactivate method, if present
-         // 2. Unbind any bound services
-         // 3. Release references to the component instance and component context
-         this.deleteComponent();
-
-         //Activator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
-
-         // reset to state UNSATISFIED
-         this.setState( STATE_UNSATISFIED );
-
-         Activator.trace("Component deactivated", m_componentMetadata);
-     }
-
-     private void disableInternal()
-     {
-         // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
-         // but not by the dependency managers
-
-         // deactivate first, this does nothing if not active/registered/factory
-         this.deactivateInternal();
-
-         Activator.trace("Disabling component", m_componentMetadata);
-
-         // close all service listeners now, they are recreated on enable
-         // Stop the dependency managers to listen to events...
-         Iterator it = m_dependencyManagers.iterator();
-         while (it.hasNext())
-         {
-             DependencyManager dm = (DependencyManager)it.next();
-             dm.close();
-         }
-         m_dependencyManagers.clear();
-
-         // we are now disabled, ready for re-enablement or complete destroyal
-         this.setState( STATE_DISABLED );
-
-         Activator.trace("Component disabled", m_componentMetadata);
-     }
-
-     /**
-      *
-      */
-     private void disposeInternal()
-     {
-         // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+    private void activateInternal()
+    {
+        // CONCURRENCY NOTE: This method is called either by the enable()
+        //     method or by the dependency managers or the reconfigure() method
+        if ( ( getState() & ( STATE_ENABLED | STATE_UNSATISFIED ) ) == 0 )
+        {
+            // This state can only be entered from the ENABLED (in the enable()
+            // method) or UNSATISFIED (missing references) states
+            return;
+        }
+
+        // go to the activating state
+        setState( STATE_ACTIVATING );
+
+        Activator.trace( "Activating component", m_componentMetadata );
+
+        // Before creating the implementation object, we are going to
+        // test if all the mandatory dependencies are satisfied
+        Iterator it = m_dependencyManagers.iterator();
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+            if ( !dm.isValid() )
+            {
+                // at least one dependency is not satisfied
+                Activator.trace( "Dependency not satisfied: " + dm.getName(), m_componentMetadata );
+                setState( STATE_UNSATISFIED );
+                return;
+            }
+        }
+
+        // 1. Load the component implementation class
+        // 2. Create the component instance and component context
+        // 3. Bind the target services
+        // 4. Call the activate method, if present
+        if ( !createComponent() )
+        {
+            // component creation failed, not active now
+            Activator.error( "Component instance could not be created, activation failed", m_componentMetadata );
+
+            // set state to unsatisfied
+            setState( STATE_UNSATISFIED );
+
+            return;
+        }
+
+        // Validation occurs before the services are provided, otherwhise the
+        // service provider's service may be called by a service requester
+        // while it is still ACTIVATING
+        setState( getSatisfiedState() );
+
+        // 5. Register provided services
+        m_serviceRegistration = registerComponentService();
+
+        Activator.trace( "Component activated", m_componentMetadata );
+    }
+
+
+    /**
+     * This method deactivates the manager, performing the following steps
+     *
+     * [0. Remove published services from the registry]
+     * 1. Call the deactivate() method, if present
+     * 2. Unbind any bound services
+     * 3. Release references to the component instance and component context
+    **/
+    private void deactivateInternal()
+    {
+        // CONCURRENCY NOTE: This method may be called either from application
+        // code or by the dependency managers or reconfiguration
+        if ( ( getState() & ( STATE_ACTIVATING | STATE_ACTIVE | STATE_REGISTERED | STATE_FACTORY ) ) == 0 )
+        {
+            // This state can only be entered from the ACTIVATING (if activation
+            // fails), ACTIVE, REGISTERED or FACTORY states
+            return;
+        }
+
+        // start deactivation by resetting the state
+        setState( STATE_DEACTIVATING );
+
+        Activator.trace( "Deactivating component", m_componentMetadata );
+
+        // 0.- Remove published services from the registry
+        unregisterComponentService();
+
+        // 1.- Call the deactivate method, if present
+        // 2. Unbind any bound services
+        // 3. Release references to the component instance and component context
+        deleteComponent();
+
+        //Activator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
+
+        // reset to state UNSATISFIED
+        setState( STATE_UNSATISFIED );
+
+        Activator.trace( "Component deactivated", m_componentMetadata );
+    }
+
+
+    private void disableInternal()
+    {
+        // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+        // but not by the dependency managers
+
+        // deactivate first, this does nothing if not active/registered/factory
+        deactivateInternal();
+
+        Activator.trace( "Disabling component", m_componentMetadata );
+
+        // close all service listeners now, they are recreated on enable
+        // Stop the dependency managers to listen to events...
+        Iterator it = m_dependencyManagers.iterator();
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+            dm.close();
+        }
+        m_dependencyManagers.clear();
+
+        // we are now disabled, ready for re-enablement or complete destroyal
+        setState( STATE_DISABLED );
+
+        Activator.trace( "Component disabled", m_componentMetadata );
+    }
+
+
+    /**
+     *
+     */
+    private void disposeInternal()
+    {
+        // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
         // but not by the dependency managers
 
-         // disable first to clean up correctly
-         this.disableInternal();
+        // disable first to clean up correctly
+        disableInternal();
+
+        // this component must not be used any more
+        setState( STATE_DESTROYED );
+
+        // release references (except component metadata for logging purposes)
+        m_activator = null;
+        m_dependencyManagers = null;
+
+        Activator.trace( "Component disposed", m_componentMetadata );
+    }
+
+
+    //---------- Component handling methods ----------------------------------
+
+    /**
+    * Method is called by {@link #activate()} in STATE_ACTIVATING or by
+    * {@link DelayedComponentManager#getService(Bundle, ServiceRegistration)}
+    * in STATE_REGISTERED.
+    * 
+    * @return <code>true</code> if creation of the component succeeded. If
+    *       <code>false</code> is returned, the cause should have been logged.
+    */
+    protected abstract boolean createComponent();
+
 
-         // this component must not be used any more
-         this.setState( STATE_DESTROYED );
+    /**
+     * Method is called by {@link #deactivate()} in STATE_DEACTIVATING
+     *
+     */
+    protected abstract void deleteComponent();
+
+
+    /**
+     * Returns the service object to be registered if the service element is
+     * specified.
+     * <p>
+     * Extensions of this class may overwrite this method to return a
+     * ServiceFactory to register in the case of a delayed or a service
+     * factory component.
+     */
+    protected abstract Object getService();
+
+
+    /**
+     * Returns the state value to set, when the component is satisfied. The
+     * return value depends on the kind of the component:
+     * <dl>
+     * <dt>Immediate</dt><dd><code>STATE_ACTIVE</code></dd>
+     * <dt>Delayed</dt><dd><code>STATE_REGISTERED</code></dd>
+     * <dt>Component Factory</dt><dd><code>STATE_FACTORY</code></dd>
+     * </dl>
+     *
+     * @return
+     */
+    private int getSatisfiedState()
+    {
+        if ( m_componentMetadata.isFactory() )
+        {
+            return STATE_FACTORY;
+        }
+        else if ( m_componentMetadata.isImmediate() )
+        {
+            return STATE_ACTIVE;
+        }
+        else
+        {
+            return STATE_REGISTERED;
+        }
+    }
+
+
+    // 5. Register provided services
+    protected ServiceRegistration registerComponentService()
+    {
+        if ( getComponentMetadata().getServiceMetadata() != null )
+        {
+            Activator.trace( "registering services", getComponentMetadata() );
+
+            // get a copy of the component properties as service properties
+            Dictionary serviceProperties = copyTo( null, getProperties() );
+
+            return getActivator().getBundleContext().registerService(
+                getComponentMetadata().getServiceMetadata().getProvides(), getService(), serviceProperties );
+        }
+
+        return null;
+    }
+
+
+    protected void unregisterComponentService()
+    {
+        if ( m_serviceRegistration != null )
+        {
+            m_serviceRegistration.unregister();
+            m_serviceRegistration = null;
+
+            Activator.trace( "unregistering the services", getComponentMetadata() );
+        }
+    }
 
-         // release references (except component metadata for logging purposes)
-         m_activator = null;
-         m_dependencyManagers = null;
-
-         Activator.trace("Component disposed", m_componentMetadata);
-     }
-
-     //---------- Component handling methods ----------------------------------
-
-     /**
-      * Method is called by {@link #activate()} in STATE_ACTIVATING or by
-      * {@link DelayedComponentManager#getService(Bundle, ServiceRegistration)}
-      * in STATE_REGISTERED.
-      */
-     protected abstract void createComponent();
-
-     /**
-      * Method is called by {@link #deactivate()} in STATE_DEACTIVATING
-      *
-      */
-     protected abstract void deleteComponent();
-
-     /**
-      * Returns the service object to be registered if the service element is
-      * specified.
-      * <p>
-      * Extensions of this class may overwrite this method to return a
-      * ServiceFactory to register in the case of a delayed or a service
-      * factory component.
-      */
-     protected abstract Object getService();
-
-     /**
-      * Returns the state value to set, when the component is satisfied. The
-      * return value depends on the kind of the component:
-      * <dl>
-      * <dt>Immediate</dt><dd><code>STATE_ACTIVE</code></dd>
-      * <dt>Delayed</dt><dd><code>STATE_REGISTERED</code></dd>
-      * <dt>Component Factory</dt><dd><code>STATE_FACTORY</code></dd>
-      * </dl>
-      *
-      * @return
-      */
-     private int getSatisfiedState() {
-         if (m_componentMetadata.isFactory())
-         {
-             return STATE_FACTORY;
-         }
-         else if (m_componentMetadata.isImmediate())
-         {
-             return STATE_ACTIVE;
-         }
-         else
-         {
-             return STATE_REGISTERED;
-         }
-     }
-
-     // 5. Register provided services
-     protected ServiceRegistration registerComponentService()
-     {
-         if ( this.getComponentMetadata().getServiceMetadata() != null )
-         {
-             Activator.trace( "registering services", this.getComponentMetadata() );
-
-             // get a copy of the component properties as service properties
-             Dictionary serviceProperties = this.copyTo( null, this.getProperties() );
-
-             return this.getActivator().getBundleContext().registerService(
-                 this.getComponentMetadata().getServiceMetadata().getProvides(), this.getService(), serviceProperties );
-         }
-
-         return null;
-     }
-
-     protected void unregisterComponentService()
-     {
-         if ( m_serviceRegistration != null )
-         {
-             m_serviceRegistration.unregister();
-             m_serviceRegistration = null;
-
-             Activator.trace( "unregistering the services", this.getComponentMetadata() );
-         }
-     }
 
     //**********************************************************************************************************
 
-    BundleComponentActivator getActivator() {
+    BundleComponentActivator getActivator()
+    {
         return m_activator;
     }
 
-    Iterator getDependencyManagers() {
+
+    Iterator getDependencyManagers()
+    {
         return m_dependencyManagers.iterator();
     }
 
+
     DependencyManager getDependencyManager( String name )
     {
-        Iterator it = this.getDependencyManagers();
+        Iterator it = getDependencyManagers();
         while ( it.hasNext() )
         {
             DependencyManager dm = ( DependencyManager ) it.next();
@@ -520,14 +564,18 @@
         return null;
     }
 
+
     /**
     * Get the object that is implementing this descriptor
     *
     * @return the object that implements the services
     */
     public abstract Object getInstance();
+
+
     protected abstract Dictionary getProperties();
 
+
     /**
      * Copies the properties from the <code>source</code> <code>Dictionary</code>
      * into the <code>target</code> <code>Dictionary</code>.
@@ -561,33 +609,44 @@
         return target;
     }
 
-    ServiceReference getServiceReference() {
+
+    ServiceReference getServiceReference()
+    {
         return ( m_serviceRegistration != null ) ? m_serviceRegistration.getReference() : null;
     }
 
+
     /**
      *
      */
-    public ComponentMetadata getComponentMetadata() {
-    	return m_componentMetadata;
+    public ComponentMetadata getComponentMetadata()
+    {
+        return m_componentMetadata;
     }
 
-    int getState() {
+
+    int getState()
+    {
         return m_state;
     }
 
+
     /**
      * sets the state of the manager
     **/
-    protected synchronized void setState(int newState) {
-        Activator.trace( "State transition : " + this.stateToString( m_state ) + " -> " + this.stateToString( newState ),
+    protected synchronized void setState( int newState )
+    {
+        Activator.trace( "State transition : " + stateToString( m_state ) + " -> " + stateToString( newState ),
             m_componentMetadata );
 
         m_state = newState;
     }
 
-    public String stateToString(int state) {
-        switch (state) {
+
+    public String stateToString( int state )
+    {
+        switch ( state )
+        {
             case STATE_DESTROYED:
                 return "Destroyed";
             case STATE_DISABLED:
@@ -607,9 +666,11 @@
             case STATE_DEACTIVATING:
                 return "Deactivating";
             default:
-                return String.valueOf(state);
+                return String.valueOf( state );
         }
     }
+
+
     /**
      * Finds the named public or protected method in the given class or any
      * super class. If such a method is found, its accessibility is enfored by
@@ -627,15 +688,14 @@
      * @throws NoSuchMethodException If no public or protected method with
      *      the given name can be found in the class or any of its super classes.
      */
-    static Method getMethod(Class clazz, String name, Class[] parameterTypes)
-        throws NoSuchMethodException
+    static Method getMethod( Class clazz, String name, Class[] parameterTypes ) throws NoSuchMethodException
     {
         // try the default mechanism first, which only yields public methods
         try
         {
-            return clazz.getMethod(name, parameterTypes);
+            return clazz.getMethod( name, parameterTypes );
         }
-        catch (NoSuchMethodException nsme)
+        catch ( NoSuchMethodException nsme )
         {
             // it is ok to not find a public method, try to find a protected now
         }
@@ -643,21 +703,22 @@
         // now use method declarations, requiring walking up the class
         // hierarchy manually. this algorithm also returns protected methods
         // which is, what we need here
-        for ( ; clazz != null; clazz = clazz.getSuperclass())
+        for ( ; clazz != null; clazz = clazz.getSuperclass() )
         {
             try
             {
-                Method method = clazz.getDeclaredMethod(name, parameterTypes);
+                Method method = clazz.getDeclaredMethod( name, parameterTypes );
 
                 // only accept a protected method, a public method should
                 // have been found above and neither private nor package
                 // protected methods are acceptable here
-                if (Modifier.isProtected(method.getModifiers())) {
-                    method.setAccessible(true);
+                if ( Modifier.isProtected( method.getModifiers() ) )
+                {
+                    method.setAccessible( true );
                     return method;
                 }
             }
-            catch (NoSuchMethodException nsme)
+            catch ( NoSuchMethodException nsme )
             {
                 // ignore for now
             }
@@ -665,7 +726,7 @@
 
         // walked up the complete super class hierarchy and still not found
         // anything, sigh ...
-        throw new NoSuchMethodException(name);
+        throw new NoSuchMethodException( name );
     }
 
 }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java?rev=568657&r1=568656&r2=568657&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java Wed Aug 22 08:28:37 2007
@@ -53,6 +53,7 @@
     // no IdentityHashSet and HashSet internally uses a HashMap anyway
     private Map m_createdComponents;
 
+
     ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata,
         ComponentRegistry componentRegistry )
     {
@@ -67,15 +68,17 @@
      */
     public ComponentInstance newInstance( Dictionary dictionary )
     {
-        return ( ComponentInstance ) this.createComponentManager( dictionary );
+        return ( ComponentInstance ) createComponentManager( dictionary );
     }
 
 
-    protected void createComponent()
+    protected boolean createComponent()
     {
         // not component to create, newInstance must be used instead
+        return true;
     }
 
+
     protected void deleteComponent()
     {
         // nothing to delete
@@ -84,11 +87,11 @@
 
     protected ServiceRegistration registerComponentService()
     {
-        Activator.trace( "registering component factory", this.getComponentMetadata() );
+        Activator.trace( "registering component factory", getComponentMetadata() );
 
-        Dictionary serviceProperties = this.getProperties();
-        return this.getActivator().getBundleContext().registerService( new String[]
-            { ComponentFactory.class.getName(), ManagedServiceFactory.class.getName() }, this.getService(),
+        Dictionary serviceProperties = getProperties();
+        return getActivator().getBundleContext().registerService( new String[]
+            { ComponentFactory.class.getName(), ManagedServiceFactory.class.getName() }, getService(),
             serviceProperties );
     }
 
@@ -105,11 +108,11 @@
         Dictionary props = new Hashtable();
 
         // 112.5.5 The Component Factory service must register with the following properties
-        props.put( ComponentConstants.COMPONENT_NAME, this.getComponentMetadata().getName() );
-        props.put( ComponentConstants.COMPONENT_FACTORY, this.getComponentMetadata().getFactoryIdentifier() );
+        props.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() );
+        props.put( ComponentConstants.COMPONENT_FACTORY, getComponentMetadata().getFactoryIdentifier() );
 
         // also register with the factory PID
-        props.put( Constants.SERVICE_PID, this.getComponentMetadata().getName() );
+        props.put( Constants.SERVICE_PID, getComponentMetadata().getName() );
 
         return props;
     }
@@ -139,7 +142,7 @@
         if ( cm == null )
         {
             // create a new instance with the current configuration
-            cm = this.createComponentManager( configuration );
+            cm = createComponentManager( configuration );
 
             // keep a reference for future updates
             m_configuredServices.put( pid, cm );
@@ -165,7 +168,7 @@
             ComponentManager cm = ( ComponentManager ) m_configuredServices.remove( pid );
             if ( cm != null )
             {
-                this.disposeComponentManager( cm );
+                disposeComponentManager( cm );
             }
         }
 
@@ -174,7 +177,7 @@
 
     public String getName()
     {
-        return "Component Factory " + this.getComponentMetadata().getName();
+        return "Component Factory " + getComponentMetadata().getName();
     }
 
 
@@ -188,13 +191,14 @@
     private ComponentManager createComponentManager( Dictionary configuration )
     {
         long componentId = m_componentRegistry.createComponentId();
-        ComponentManager cm = ManagerFactory.createManager( this.getActivator(), this.getComponentMetadata(), componentId );
+        ComponentManager cm = ManagerFactory.createManager( getActivator(), getComponentMetadata(),
+            componentId );
 
         // add the new component to the activators instances
-        this.getActivator().getInstanceReferences().add( cm );
+        getActivator().getInstanceReferences().add( cm );
 
         // register with the internal set of created components
-        m_createdComponents.put(cm, cm);
+        m_createdComponents.put( cm, cm );
 
         // inject configuration if possible
         if ( cm instanceof ImmediateComponentManager )
@@ -208,12 +212,14 @@
         return cm;
     }
 
-    private void disposeComponentManager(ComponentManager cm) {
+
+    private void disposeComponentManager( ComponentManager cm )
+    {
         // remove from created components
         m_createdComponents.remove( cm );
 
         // remove from activators list
-        this.getActivator().getInstanceReferences().remove( cm );
+        getActivator().getInstanceReferences().remove( cm );
 
         // finally dispose it
         cm.dispose();

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java?rev=568657&r1=568656&r2=568657&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java Wed Aug 22 08:28:37 2007
@@ -18,15 +18,17 @@
  */
 package org.apache.felix.scr;
 
+
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceRegistration;
 
+
 /**
  * The <code>DelayedComponentManager</code> TODO
  *
  * @author fmeschbe
- * @version $Rev: 538123 $, $Date$
+ * @version $Rev$, $Date$
  */
 public class DelayedComponentManager extends ImmediateComponentManager implements ServiceFactory
 {
@@ -41,47 +43,55 @@
         super( activator, metadata, componentId );
     }
 
-    protected void createComponent()
+
+    protected boolean createComponent()
     {
         // nothing to do here for a delayed component, will be done in the
         // getService method for the first bundle acquiring the component
+        return true;
     }
 
+
     protected void deleteComponent()
     {
         // only have to delete, if there is actually an instance
-        if (this.getInstance() != null) {
+        if ( getInstance() != null )
+        {
             super.deleteComponent();
         }
     }
 
+
     protected Object getService()
     {
         return this;
     }
 
+
     //---------- ServiceFactory interface -------------------------------------
 
     public Object getService( Bundle arg0, ServiceRegistration arg1 )
     {
-        Activator.trace("DelayedComponentServiceFactory.getService()", this.getComponentMetadata());
+        Activator.trace( "DelayedComponentServiceFactory.getService()", getComponentMetadata() );
         // When the getServiceMethod is called, the implementation object must be created
         // unless another bundle has already retrievd it
 
-        if (this.getInstance() == null) {
+        if ( getInstance() == null )
+        {
             super.createComponent();
 
             // if component creation failed, we were deactivated and the state
             // is not REGISTERED any more. Otherwise go to standard ACTIVE
             // state now
-            if (this.getState() == STATE_REGISTERED)
+            if ( getState() == STATE_REGISTERED )
             {
-                this.setState( STATE_ACTIVE );
+                setState( STATE_ACTIVE );
             }
         }
 
-        return this.getInstance();
+        return getInstance();
     }
+
 
     public void ungetService( Bundle arg0, ServiceRegistration arg1, Object arg2 )
     {

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java?rev=568657&r1=568656&r2=568657&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java Wed Aug 22 08:28:37 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.scr;
 
+
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -52,15 +53,16 @@
     // the component properties, also used as service properties
     private Dictionary m_properties;
 
+
     /**
      * The constructor receives both the activator and the metadata
      *
      * @param activator
      * @param metadata
      */
-    ImmediateComponentManager(BundleComponentActivator activator, ComponentMetadata metadata, long componentId)
+    ImmediateComponentManager( BundleComponentActivator activator, ComponentMetadata metadata, long componentId )
     {
-        super(activator, metadata);
+        super( activator, metadata );
 
         m_componentId = componentId;
     }
@@ -72,21 +74,27 @@
     // 4. Call the activate method, if present
     // if this method is overwritten, the deleteComponent method should
     // also be overwritten
-    protected void createComponent()
+    protected boolean createComponent()
     {
         ComponentContext tmpContext = new ComponentContextImpl( this );
-        Object tmpComponent = this.createImplementationObject( tmpContext );
+        Object tmpComponent = createImplementationObject( tmpContext );
 
-        // if something failed craeating the object, we fell back to
-        // unsatisfied !!
-        if (tmpComponent != null) {
-            m_componentContext = tmpContext;
-            m_implementationObject = tmpComponent;
+        // if something failed creating the component instance, return false
+        if ( tmpComponent == null )
+        {
+            return false;
         }
+
+        // otherwise set the context and component instance and return true
+        m_componentContext = tmpContext;
+        m_implementationObject = tmpComponent;
+        return true;
     }
 
-    protected void deleteComponent() {
-        this.disposeImplementationObject( m_implementationObject, m_componentContext );
+
+    protected void deleteComponent()
+    {
+        disposeImplementationObject( m_implementationObject, m_componentContext );
         m_implementationObject = null;
         m_componentContext = null;
         m_properties = null;
@@ -100,11 +108,14 @@
     *
     * @return the object that implements the services
     */
-    public Object getInstance() {
+    public Object getInstance()
+    {
         return m_implementationObject;
     }
 
-    protected Object createImplementationObject(ComponentContext componentContext) {
+
+    protected Object createImplementationObject( ComponentContext componentContext )
+    {
         Object implementationObject;
 
         // 1. Load the component implementation class
@@ -113,23 +124,22 @@
         try
         {
             // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
-            Class c = this.getActivator().getBundleContext().getBundle().loadClass(this.getComponentMetadata().getImplementationClassName());
+            Class c = getActivator().getBundleContext().getBundle().loadClass(
+                getComponentMetadata().getImplementationClassName() );
 
             // 112.4.4 The class must be public and have a public constructor without arguments so component instances
             // may be created by the SCR with the newInstance method on Class
             implementationObject = c.newInstance();
         }
-        catch (Exception ex)
+        catch ( Exception ex )
         {
-            // failed to instantiate, deactivate the component and return null
-            Activator.exception( "Error during instantiation of the implementation object", this.getComponentMetadata(), ex );
-            this.deactivate();
+            // failed to instantiate, return null
+            Activator.exception( "Error during instantiation of the implementation object", getComponentMetadata(), ex );
             return null;
         }
 
-
         // 3. Bind the target services
-        Iterator it = this.getDependencyManagers();
+        Iterator it = getDependencyManagers();
         while ( it.hasNext() )
         {
             // if a dependency turned unresolved since the validation check,
@@ -139,8 +149,16 @@
             if ( !dm.bind( implementationObject ) )
             {
                 Activator.error( "Cannot create component instance due to failure to bind reference " + dm.getName(),
-                    this.getComponentMetadata() );
-                this.deactivate();
+                    getComponentMetadata() );
+
+                // make sure, we keep no bindings
+                it = getDependencyManagers();
+                while ( it.hasNext() )
+                {
+                    dm = ( DependencyManager ) it.next();
+                    dm.unbind( implementationObject );
+                }
+
                 return null;
             }
         }
@@ -157,23 +175,34 @@
         catch ( NoSuchMethodException ex )
         {
             // We can safely ignore this one
-            Activator.trace( "activate() method is not implemented", this.getComponentMetadata() );
+            Activator.trace( "activate() method is not implemented", getComponentMetadata() );
         }
         catch ( IllegalAccessException ex )
         {
             // Ignored, but should it be logged?
-            Activator.trace( "activate() method cannot be called", this.getComponentMetadata() );
+            Activator.trace( "activate() method cannot be called", getComponentMetadata() );
         }
         catch ( InvocationTargetException ex )
         {
             // 112.5.8 If the activate method throws an exception, SCR must log an error message
-            // containing the exception with the Log Service
-            Activator.exception( "The activate method has thrown an exception", this.getComponentMetadata(), ex );
+            // containing the exception with the Log Service and activation fails
+            Activator.exception( "The activate method has thrown an exception", getComponentMetadata(), ex );
+
+            // make sure, we keep no bindings
+            it = getDependencyManagers();
+            while ( it.hasNext() )
+            {
+                DependencyManager dm = ( DependencyManager ) it.next();
+                dm.unbind( implementationObject );
+            }
+
+            return null;
         }
 
         return implementationObject;
     }
 
+
     protected void disposeImplementationObject( Object implementationObject, ComponentContext componentContext )
     {
         // 1. Call the deactivate method, if present
@@ -188,22 +217,22 @@
         catch ( NoSuchMethodException ex )
         {
             // We can safely ignore this one
-            Activator.trace( "deactivate() method is not implemented", this.getComponentMetadata() );
+            Activator.trace( "deactivate() method is not implemented", getComponentMetadata() );
         }
         catch ( IllegalAccessException ex )
         {
             // Ignored, but should it be logged?
-            Activator.trace( "deactivate() method cannot be called", this.getComponentMetadata() );
+            Activator.trace( "deactivate() method cannot be called", getComponentMetadata() );
         }
         catch ( InvocationTargetException ex )
         {
             // 112.5.12 If the deactivate method throws an exception, SCR must log an error message
             // containing the exception with the Log Service and continue
-            Activator.exception( "The deactivate method has thrown an exception", this.getComponentMetadata(), ex );
+            Activator.exception( "The deactivate method has thrown an exception", getComponentMetadata(), ex );
         }
 
         // 2. Unbind any bound services
-        Iterator it = this.getDependencyManagers();
+        Iterator it = getDependencyManagers();
 
         while ( it.hasNext() )
         {
@@ -215,6 +244,7 @@
         // nothing to do, we keep no references on per-Bundle services
     }
 
+
     /**
      * Returns the service object to be registered if the service element is
      * specified.
@@ -223,14 +253,18 @@
      * ServiceFactory to register in the case of a delayed or a service
      * factory component.
      */
-    protected Object getService() {
+    protected Object getService()
+    {
         return m_implementationObject;
     }
 
-    protected void setFactoryProperties(Dictionary dictionary) {
-        m_factoryProperties = this.copyTo( null, dictionary );
+
+    protected void setFactoryProperties( Dictionary dictionary )
+    {
+        m_factoryProperties = copyTo( null, dictionary );
     }
 
+
     /**
      * Returns the (private copy) of the Component properties to be used
      * for the ComponentContext as well as eventual service registration.
@@ -249,30 +283,31 @@
         {
 
             // 1. the properties from the component descriptor
-            Dictionary props = this.copyTo( null, this.getComponentMetadata().getProperties() );
+            Dictionary props = copyTo( null, getComponentMetadata().getProperties() );
 
             // 2. overlay with Configuration Admin properties
-            ConfigurationAdmin ca = this.getActivator().getConfigurationAdmin();
+            ConfigurationAdmin ca = getActivator().getConfigurationAdmin();
             if ( ca != null )
             {
                 try
                 {
-                    Configuration cfg = ca.getConfiguration( this.getComponentMetadata().getName() );
-                    if (cfg != null) {
-                        this.copyTo( props, cfg.getProperties() );
+                    Configuration cfg = ca.getConfiguration( getComponentMetadata().getName() );
+                    if ( cfg != null )
+                    {
+                        copyTo( props, cfg.getProperties() );
                     }
                 }
                 catch ( IOException ioe )
                 {
-                    Activator.exception( "Problem getting Configuration", this.getComponentMetadata(), ioe );
+                    Activator.exception( "Problem getting Configuration", getComponentMetadata(), ioe );
                 }
             }
 
             // 3. copy any component factory properties, not supported yet
-            this.copyTo( props, m_factoryProperties );
+            copyTo( props, m_factoryProperties );
 
             // 4. set component.name and component.id
-            props.put( ComponentConstants.COMPONENT_NAME, this.getComponentMetadata().getName() );
+            props.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() );
             props.put( ComponentConstants.COMPONENT_ID, new Long( m_componentId ) );
 
             m_properties = props;

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java?rev=568657&r1=568656&r2=568657&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java Wed Aug 22 08:28:37 2007
@@ -53,9 +53,10 @@
     /* (non-Javadoc)
      * @see org.apache.felix.scr.AbstractComponentManager#createComponent()
      */
-    protected void createComponent()
+    protected boolean createComponent()
     {
         // nothing to do, this is handled by getService
+        return true;
     }
 
 
@@ -98,17 +99,18 @@
         Object service = createImplementationObject( serviceContext );
 
         // register the components component context if successfull
-        if (service != null) {
+        if ( service != null )
+        {
             serviceContext.setImplementationObject( service );
             serviceContexts.put( service, serviceContext );
 
             // if this is the first use of this component, switch to ACTIVE state
-            if (getState() == STATE_REGISTERED)
+            if ( getState() == STATE_REGISTERED )
             {
                 setState( STATE_ACTIVE );
             }
         }
-        
+
         return service;
     }
 
@@ -124,7 +126,7 @@
         // private ComponentContext and implementation instances
         ComponentContext serviceContext = ( ComponentContext ) serviceContexts.remove( service );
         disposeImplementationObject( service, serviceContext );
-        
+
         // if this was the last use of the component, go back to REGISTERED state
         if ( serviceContexts.isEmpty() && getState() == STATE_ACTIVE )
         {
@@ -132,39 +134,47 @@
         }
     }
 
-    private static class BundleComponentContext extends ComponentContextImpl implements ComponentInstance {
-        
+    private static class BundleComponentContext extends ComponentContextImpl implements ComponentInstance
+    {
+
         private Bundle m_usingBundle;
         private Object m_implementationObject;
 
-        BundleComponentContext(AbstractComponentManager componentManager, Bundle usingBundle) {
-            super(componentManager);
-            
+
+        BundleComponentContext( AbstractComponentManager componentManager, Bundle usingBundle )
+        {
+            super( componentManager );
+
             m_usingBundle = usingBundle;
         }
-        
+
+
         private void setImplementationObject( Object implementationObject )
         {
             m_implementationObject = implementationObject;
         }
-        
+
+
         public Bundle getUsingBundle()
         {
             return m_usingBundle;
         }
-        
+
+
         public ComponentInstance getComponentInstance()
         {
             return this;
         }
-        
+
+
         //---------- ComponentInstance interface ------------------------------
-        
+
         public Object getInstance()
         {
             return m_implementationObject;
         }
-        
+
+
         public void dispose()
         {
             getComponentManager().dispose();