FELIX-3744 set implementation object before modifying service properties

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1406395 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/changelog.txt b/scr/changelog.txt
index 7927869..487c034 100644
--- a/scr/changelog.txt
+++ b/scr/changelog.txt
@@ -59,7 +59,7 @@
     * [FELIX-3725] - [DS] hidden dependency on spring junit wrapper from pax exam
     * [FELIX-3726] - Reference target filters defined as component properties are ignored
     * [FELIX-3727] - [DS] NPE during shutdown
-
+    * [FELIX-3744] -  set implementation object before modifying service properties
 ** Improvement
     * [FELIX-2895] - Allow the use of a property to tell SCR to always discover Service Component files even if there's no wildcard in the name
     * [FELIX-3016] - Activator log level cannot be changed dynamically through Configuration Admin
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index 7648ba4..ceed436 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -115,8 +115,15 @@
         }
         if ( m_implementationObject == null )
         {
-            ComponentContextImpl tmpContext = new ComponentContextImpl( this );
-            Object tmpComponent = createImplementationObject( tmpContext );
+            final ComponentContextImpl tmpContext = new ComponentContextImpl( this );
+            Object tmpComponent = createImplementationObject( tmpContext, new SetImplementationObject()
+            {
+                public void setImplementationObject( Object implementationObject )
+                {
+                    m_componentContext = tmpContext;
+                    m_implementationObject = implementationObject;
+                }
+            } );
 
             // if something failed creating the component instance, return false
             if ( tmpComponent == null )
@@ -125,8 +132,6 @@
             }
 
             // otherwise set the context and component instance and return true
-            m_componentContext = tmpContext;
-            m_implementationObject = tmpComponent;
             log( LogService.LOG_DEBUG, "Set implementation object for component {0}", new Object[] { getName() },  null );
 
             //notify that component was successfully created so any optional circular dependencies can be retried
@@ -173,8 +178,11 @@
         return m_implementationObject;
     }
 
+    protected interface SetImplementationObject {
+        void setImplementationObject(Object implementationObject);
+    }
 
-    protected Object createImplementationObject( ComponentContext componentContext )
+    protected Object createImplementationObject( ComponentContext componentContext, SetImplementationObject setter )
     {
         final Class implementationObjectClass;
         final Object implementationObject;
@@ -245,6 +253,7 @@
         }
         else
         {
+            setter.setImplementationObject( implementationObject );
             setServiceProperties( result );
         }
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
index c315e84..1798f22 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
@@ -112,40 +112,39 @@
 
         // When the getServiceMethod is called, the implementation object must be created
 
-            try
+        try
+        {
+            if ( !collectDependencies() )
             {
-                if ( !collectDependencies() )
-                {
-                    log(
-                            LogService.LOG_INFO,
-                            "getService (ServiceFactory) did not win collecting dependencies, try creating object anyway.",
-                            null );
+                log(
+                        LogService.LOG_INFO,
+                        "getService (ServiceFactory) did not win collecting dependencies, try creating object anyway.",
+                        null );
 
-                }
-                else
-                {
-                    log(
-                            LogService.LOG_DEBUG,
-                            "getService (ServiceFactory) won collecting dependencies, proceed to creating object.",
-                            null );
-
-                }
             }
-            catch ( IllegalStateException e )
+            else
             {
-                //cannot obtain service from a required reference
-                return null;
+                log(
+                        LogService.LOG_DEBUG,
+                        "getService (ServiceFactory) won collecting dependencies, proceed to creating object.",
+                        null );
+
             }
-            // private ComponentContext and implementation instances
-            BundleComponentContext serviceContext = new BundleComponentContext( this, bundle );
-            Object service = createImplementationObject( serviceContext );
-
-            // register the components component context if successfull
-            if ( service != null )
+        }
+        catch ( IllegalStateException e )
+        {
+            //cannot obtain service from a required reference
+            return null;
+        }
+        // private ComponentContext and implementation instances
+        final BundleComponentContext serviceContext = new BundleComponentContext( this, bundle );
+        Object service = createImplementationObject( serviceContext, new SetImplementationObject()
+        {
+            public void setImplementationObject( Object implementationObject )
             {
-                serviceContext.setImplementationObject( service );
+                serviceContext.setImplementationObject( implementationObject );
 
-                serviceContexts.put( service, serviceContext );
+                serviceContexts.put( implementationObject, serviceContext );
 
                 // if this is the first use of this component, switch to ACTIVE state
                 if ( getState() == STATE_REGISTERED )
@@ -153,14 +152,17 @@
                     changeState( Active.getInstance() );
                 }
             }
-            else
-            {
-                // log that the service factory component cannot be created (we don't
-                // know why at this moment; this should already have been logged)
-                log( LogService.LOG_ERROR, "Failed creating the component instance; see log for reason", null );
-            }
+        } );
 
-            return service;
+        // register the components component context if successfull
+        if ( service == null )
+        {
+            // log that the service factory component cannot be created (we don't
+            // know why at this moment; this should already have been logged)
+            log( LogService.LOG_ERROR, "Failed creating the component instance; see log for reason", null );
+        }
+
+        return service;
     }