FELIX-3895 (https://issues.apache.org/jira/browse/FELIX-3895) - iPOJO instance is not shown (with the "arch" commands) if constructor is failing

The architecture service is now published even is the instance is stopped. This, in combination of the declaration bindings error (available through the instance declaration service)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1480353 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java b/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java
index af6be2a..8b82a00 100644
--- a/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java
+++ b/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java
@@ -20,6 +20,7 @@
 
 import static java.lang.String.format;
 
+import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -87,12 +88,21 @@
     @Requires(optional = true)
     private HandlerFactory[] m_handlers;
 
+    /**
+     * The instance declaration services.
+     */
     @Requires(optional = true)
     private InstanceDeclaration[] m_instances;
 
+    /**
+     * The type declaration services.
+     */
     @Requires(optional = true)
     private TypeDeclaration[] m_types;
 
+    /**
+     * The extension declaration services.
+     */
     @Requires(optional = true)
     private ExtensionDeclaration[] m_extensions;
 
@@ -147,30 +157,40 @@
      */
     @Descriptor("Display the architecture of a specific instance")
     public void instance(@Descriptor("target instance name") String instance) {
+
+        StringBuilder sb = new StringBuilder();
+
         for (Architecture m_arch : m_archs) {
             InstanceDescription id = m_arch.getInstanceDescription();
             if (id.getName().equalsIgnoreCase(instance)) {
-                System.out.println(id.getDescription());
-                return;
+                sb.append(id.getDescription());
+                sb.append('\n');
             }
         }
 
         for (InstanceDeclaration instanceDeclaration : m_instances) {
             if (!instanceDeclaration.getStatus().isBound()) {
                 if (instance.equals(name(instanceDeclaration.getConfiguration()))) {
-                    System.out.println(format("Instance %s not bound to its factory%n", instance));
-                    System.out.println(format(" type: %s%n", instanceDeclaration.getComponentName()));
-                    System.out.println(format(" -> %s%n", instanceDeclaration.getStatus().getMessage()));
+                    sb.append(format("InstanceDeclaration %s not bound to its factory%n", instance));
+                    sb.append(format(" type: %s%n", instanceDeclaration.getComponentName()));
+                    sb.append(format(" reason: %s%n", instanceDeclaration.getStatus().getMessage()));
                     Throwable throwable = instanceDeclaration.getStatus().getThrowable();
                     if (throwable != null) {
-                        throwable.printStackTrace(System.out);
+                        ByteArrayOutputStream os = new ByteArrayOutputStream();
+                        throwable.printStackTrace(new PrintStream(os));
+                        sb.append(" throwable: ");
+                        sb.append(os.toString());
                     }
-                    return;
                 }
             }
         }
 
-        System.err.println("Instance " + instance + " not found");
+        if (sb.length() == 0) {
+            System.err.printf("Instance named '%s' not found", instance);
+        } else {
+            System.out.print(sb);
+        }
+
     }
     
     /**
@@ -215,9 +235,10 @@
             if (!type.getStatus().isBound()) {
                 // Unbound: maybe private or public type
                 System.out.printf("Factory %s is not bound%n", type.getComponentName());
-                System.out.printf("  -> %s%n", type.getStatus().getMessage());
+                System.out.printf("  reason: %s%n", type.getStatus().getMessage());
                 Throwable throwable = type.getStatus().getThrowable();
                 if (throwable != null) {
+                    System.out.print("  throwable: ");
                     throwable.printStackTrace(System.out);
                 }
             } else {
diff --git a/ipojo/runtime/api-it/pom.xml b/ipojo/runtime/api-it/pom.xml
index aaa8ace..d989b49 100644
--- a/ipojo/runtime/api-it/pom.xml
+++ b/ipojo/runtime/api-it/pom.xml
@@ -195,6 +195,12 @@
             <artifactId>org.apache.felix.ipojo.handler.whiteboard</artifactId>
             <version>1.4.0</version>
             <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>org.osgi.core</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
         <dependency>
diff --git a/ipojo/runtime/composite-it/pom.xml b/ipojo/runtime/composite-it/pom.xml
index ca9a55d..6851f5b 100644
--- a/ipojo/runtime/composite-it/pom.xml
+++ b/ipojo/runtime/composite-it/pom.xml
@@ -205,6 +205,12 @@
             <artifactId>osgi-helpers</artifactId>
             <version>0.6.1-SNAPSHOT</version>
             <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.osgi</groupId>
+                    <artifactId>org.osgi.core</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
         <dependency>
@@ -388,7 +394,7 @@
                     <groupId>org.osgi</groupId>
                     <artifactId>org.osgi.core</artifactId>
                     <version>4.3.1</version>
-                    <scope>provided</scope>
+                    <scope>compile</scope>
                 </dependency>
             </dependencies>
         </profile>
diff --git a/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml b/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml
index ca65cf1..e527811 100644
--- a/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml
+++ b/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml
@@ -31,7 +31,6 @@
 
     <modelVersion>4.0.0</modelVersion>
 
-    <groupId>org.apache.felix</groupId>
     <artifactId>ipojo-composite-import-export-test</artifactId>
 
     <name>${project.artifactId}</name>
diff --git a/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java b/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java
index ef86997..ade8665 100644
--- a/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java
+++ b/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java
@@ -88,7 +88,8 @@
         CompositeManager cm = (CompositeManager) ci;

         ServiceContext sc = cm.getServiceContext();

         try {

-            assertEquals("Check number of factories imported", sc.getServiceReferences(Factory.class.getName(), null).length, getContext().getServiceReferences(Factory.class.getName(), null).length);

+            assertEquals("Check number of factories imported", sc.getServiceReferences(Factory.class.getName(),

+                    null).length, getContext().getServiceReferences(Factory.class.getName(), null).length);

         } catch (InvalidSyntaxException e) {

             fail("Invalid filter : " + e.getMessage());

         }

diff --git a/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java b/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
index b0bf76b..bb3b603 100644
--- a/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
+++ b/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
@@ -26,6 +26,9 @@
 import org.ops4j.pax.exam.spi.reactors.PerMethod;
 import org.ow2.chameleon.testing.helpers.BaseTest;
 
+import java.util.Arrays;
+import java.util.List;
+
 /**
  * Bootstrap the test from this project
  */
@@ -44,4 +47,11 @@
     public boolean deployiPOJOComposite() {
         return true;
     }
+
+    @Override
+    protected List<String> getExtraExports() {
+        return Arrays.asList(
+                "org.apache.felix.ipojo.runtime.core.components"
+        );
+    }
 }
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java
index 802ddcb..87793fc 100644
--- a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java
@@ -50,7 +50,7 @@
 
 
     /**
-     * Gets the list of contained instance in the describe instance.
+     * Gets the list of contained instance in the described instance.
      * This list contains only instances who exposed their architecture.
      * @return the list of contained instances.
      */
@@ -58,15 +58,15 @@
         // Get instances description of internal instance
         ServiceContext internal = ((CompositeManager) m_instance).getServiceContext();
         try {
-            ServiceReference[]refs = internal.getServiceReferences(Architecture.class.getName(), null);
+            ServiceReference[] refs = internal.getServiceReferences(Architecture.class.getName(), null);
             if (refs != null) {
-                InstanceDescription[] descs = new InstanceDescription[refs.length];
+                InstanceDescription[] desc = new InstanceDescription[refs.length];
                 for (int i = 0; i < refs.length; i++) {
                     Architecture arch = (Architecture) internal.getService(refs[i]);
-                    descs[i] = arch.getInstanceDescription();
+                    desc[i] = arch.getInstanceDescription();
                     internal.ungetService(refs[i]);
                 }
-                return descs;
+                return desc;
             }
         } catch (InvalidSyntaxException e) {
             // Cannot happen
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
index 817ec08..8286c86 100644
--- a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
@@ -19,18 +19,23 @@
 package org.apache.felix.ipojo.composite.architecture;

 

 import java.util.Dictionary;

+import java.util.Hashtable;

 

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.InstanceStateListener;

 import org.apache.felix.ipojo.architecture.Architecture;

 import org.apache.felix.ipojo.architecture.InstanceDescription;

 import org.apache.felix.ipojo.composite.CompositeHandler;

 import org.apache.felix.ipojo.metadata.Element;

+import org.osgi.framework.ServiceRegistration;

 

 /**

  * Composite Architecture Handler.

  * 

  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

  */

-public class ArchitectureHandler extends CompositeHandler implements Architecture {

+public class ArchitectureHandler extends CompositeHandler implements Architecture, InstanceStateListener {

 

     /**

      * Name of the component.

@@ -38,37 +43,66 @@
     private String m_name;

 

     /**

+     * The Architecture service registration.

+     */

+    private ServiceRegistration m_serviceRegistration;

+

+    /**

      * Configure the handler.

-     * 

-     * @param metadata : the metadata of the component

+     *

+     * @param metadata      : the metadata of the component

      * @param configuration : the instance configuration

-     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,

-     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

      */

     public void configure(Element metadata, Dictionary configuration) {

-        m_name = (String) configuration.get("instance.name");

+        m_name = (String) configuration.get(Factory.INSTANCE_NAME_PROPERTY);

+        Dictionary<String, String> dict = new Hashtable<String, String>();

+        dict.put(ARCHITECTURE_INSTANCE, m_name);

+

+        debug("Registering architecture service for " + m_name);

+        m_serviceRegistration = getCompositeManager().getContext().registerService(Architecture.class.getName(), this, dict);

+

+        // We can't use the regular handler stateChanged method as this method is not called when the instance is

+        // disposed. This handler stays actives until the instance disposal.

+        getCompositeManager().addInstanceStateListener(this);

     }

 

     /**

-     * Stop the handler.

+     * Stop method.

+     *

      * @see org.apache.felix.ipojo.Handler#stop()

      */

     public void stop() {

+        // Nothing do do when stopping.

+    }

+

+    /**

+     * Start method.

+     *

+     * @see org.apache.felix.ipojo.Handler#start()

+     */

+    public void start() {

         // Nothing to do.

     }

 

     /**

-     * Start the handler.

-     * @see org.apache.felix.ipojo.Handler#start()

+     * The instance lifecycle listener callback.

+     * When we receive the DISPOSED state, the architecture is unregistered from the service registry.

+     * @param instance the changing instance the instance, meaningless in our case.

+     * @param newState the new instance state the new instance state.

      */

-    public void start() { 

-        info("Start composite architecture handler with " + m_name + " name");

+    public void stateChanged(ComponentInstance instance, int newState) {

+        if (newState == ComponentInstance.DISPOSED && m_serviceRegistration != null) {

+            debug("Withdrawing the architecture service of " + m_name + " due to instance disposal");

+            m_serviceRegistration.unregister();

+            m_serviceRegistration = null;

+        }

     }

 

     /**

      * Get the instance description.

      * @return the instance description

-     * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()

+     * @see org.apache.felix.ipojo.architecture.Architecture#getInstanceDescription() ()

      */

     public InstanceDescription getInstanceDescription() {

         return getCompositeManager().getInstanceDescription();

diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
index f7fe811..20b2a7b 100644
--- a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
@@ -197,7 +197,8 @@
     public void unbindFactory(Factory factory) {

         boolean implicated = false;

         for (int i = 0; i < m_configurations.length; i++) {

-            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factory.getName())) {

+            if (m_configurations[i].getInstance() != null

+                    && m_configurations[i].getFactory().equals(factory.getName())) {

                 m_configurations[i].setInstance(null);

                 m_configurations[i].setFactory(null);

                 implicated = true;

@@ -340,7 +341,7 @@
 

     /**

      * Check handler validity.

-     * The method update the validaity of the handler.

+     * The method updates the validity of the handler.

      */

     private void checkValidity() {

         for (int i = 0; i < m_configurations.length; i++) {

@@ -362,8 +363,9 @@
     public void stateChanged(ComponentInstance instance, int newState) {

         switch (newState) {

             case ComponentInstance.DISPOSED:

+                break;  // Should not happen

             case ComponentInstance.STOPPED:

-                break; // Should not happen

+                break;  // Should not happen

             case ComponentInstance.VALID:

                 if (!getValidity()) {

                     checkValidity();

@@ -392,7 +394,8 @@
                 if (m_configurations[i].getInstance().getState() == ComponentInstance.VALID) {

                     return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject();

                 } else {

-                    error("An object cannot be get from the instance of the type " + type + ": invalid instance" + m_configurations[i].getInstance().getInstanceDescription().getDescription());

+                    error("An object cannot be get from the instance of the type " + type + ": invalid instance" +

+                            m_configurations[i].getInstance().getInstanceDescription().getDescription());

                     return null;

                 }

             }

diff --git a/ipojo/runtime/composite/src/main/resources/metadata.xml b/ipojo/runtime/composite/src/main/resources/metadata.xml
index 0f6262b..13b2163 100644
--- a/ipojo/runtime/composite/src/main/resources/metadata.xml
+++ b/ipojo/runtime/composite/src/main/resources/metadata.xml
@@ -38,8 +38,6 @@
 	<handler

 		classname="org.apache.felix.ipojo.composite.architecture.ArchitectureHandler"

 		name="architecture" type="composite" architecture="false">

-		<provides>

-			<property field="m_name" name="architecture.instance"/>

-		</provides>

+		<!-- the architecture service is published by the handler manually -->

 	</handler>

 </ipojo>
\ No newline at end of file
diff --git a/ipojo/runtime/core-it/pom.xml b/ipojo/runtime/core-it/pom.xml
index 1712f89..ebba39a 100644
--- a/ipojo/runtime/core-it/pom.xml
+++ b/ipojo/runtime/core-it/pom.xml
@@ -211,6 +211,12 @@
             <artifactId>osgi-helpers</artifactId>
             <version>0.6.1-SNAPSHOT</version>
             <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.osgi</groupId>
+                    <artifactId>org.osgi.core</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
 
@@ -395,7 +401,7 @@
                     <groupId>org.osgi</groupId>
                     <artifactId>org.osgi.core</artifactId>
                     <version>4.3.1</version>
-                    <scope>provided</scope>
+                    <scope>compile</scope>
                 </dependency>
             </dependencies>
         </profile>
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java
index 2ef8b3d..149a53f 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java
@@ -29,8 +29,7 @@
 import java.util.Dictionary;
 import java.util.Hashtable;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.*;
 import static org.junit.Assert.assertNotNull;
 
 public class TestArchitecture extends Common {
@@ -44,11 +43,6 @@
      */
     ComponentInstance instance2;
 
-    /**
-     * Instance without configuration.
-     */
-    ComponentInstance instance3;
-
     @Before
     public void setUp() {
         String type = "CONFIG-FooProviderType-4";
@@ -118,5 +112,35 @@
 
     }
 
+    /**
+     * Test checking the availability of the architecture instance according to the instance state.
+     * The architecture instance is available even in the STOPPED state.
+     */
+    @Test
+    public void testArchitectureServiceAvailability() {
+        String instanceName = instance1.getInstanceName();
+        // Check architecture of instance1
+        Architecture arch = ipojoHelper.getArchitectureByName(instanceName);
+        assertNotNull(arch);
+        assertEquals(ComponentInstance.VALID, arch.getInstanceDescription().getState());
+
+        // We stop the instance
+        instance1.stop();
+        arch = ipojoHelper.getArchitectureByName(instanceName);
+        assertNotNull(arch);
+        assertEquals(ComponentInstance.STOPPED, arch.getInstanceDescription().getState());
+
+        // Restart.
+        instance1.start();
+        arch = ipojoHelper.getArchitectureByName(instanceName);
+        assertNotNull(arch);
+        assertEquals(ComponentInstance.VALID, arch.getInstanceDescription().getState());
+
+        // Disposal
+        instance1.dispose();
+        arch = ipojoHelper.getArchitectureByName(instanceName);
+        assertNull(arch);
+    }
+
 
 }
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java b/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java
index b7f8c90..00ff060 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java
@@ -22,10 +22,10 @@
 import org.apache.felix.ipojo.HandlerManagerFactory;

 import org.apache.felix.ipojo.architecture.Architecture;

 import org.apache.felix.ipojo.runtime.externalhandlers.services.CheckService;

-import org.junit.After;

 import org.junit.Before;

 import org.junit.Test;

 import org.osgi.framework.ServiceReference;

+import org.ow2.chameleon.testing.helpers.Dumps;

 

 import java.util.Dictionary;

 import java.util.Properties;

@@ -36,156 +36,12 @@
 

 public class HandlerTest extends Common {

 

-	ComponentInstance instance;

+    ComponentInstance instance;

 

     @Before

-	public void setUp() {

-		Properties props = new Properties();

-		props.put("instance.name","HandlerTest-1");

-		props.put("csh.simple", "simple");

-		Properties p = new Properties();

-		p.put("a", "a");

-		p.put("b", "b");

-		p.put("c", "c");

-		props.put("csh.map", p);

-		instance = ipojoHelper.createComponentInstance("HANDLER-HandlerTester", props);

-	}

-    

-	@After

-	public void tearDown() {

-		instance.dispose();

-		instance = null;

-	}

-

-    @Test

-	public void testConfiguration1() {

-		// Check the availability of CheckService

-	    String name = "HandlerTest-1";

-		ServiceReference sr = null;

-		ServiceReference[] refs = null;

-        String filter = "("+"instance.name"+"="+name+")";

-        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

-        if(refs != null) { sr = refs[0]; }

-        

-		assertNotNull("Check the check service availability", sr);

-		

-		CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

-		Dictionary<String, Object> p = cs.getProps();

-		assertEquals("Assert 'simple' equality", p.get("Simple"), "simple");

-		assertEquals("Assert 'a' equality", p.get("Map1"), "a");

-		assertEquals("Assert 'b' equality", p.get("Map2"), "b");

-		assertEquals("Assert 'c' equality", p.get("Map3"), "c");

-	}

-

-    @Test

-	public void testConfiguration2() {

-		// Check the availability of CheckService

-	    String name = "HandlerTest-2";

-        ServiceReference sr = null;

-        ServiceReference[] refs = null;

-        String filter = "("+"instance.name"+"="+name+")";

-

-        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

-

-        if(refs != null) { sr = refs[0]; }

-		assertNotNull("Check the check service availability", sr);

-		

-		CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

-        Dictionary<String, Object> p = cs.getProps();

-		assertEquals("Assert 'simple' equality", p.get("Simple"), "Simple");

-		assertEquals("Assert 'a' equality", p.get("Map1"), "a");

-		assertEquals("Assert 'b' equality", p.get("Map2"), "b");

-		assertEquals("Assert 'c' equality", p.get("Map3"), "c");

-	}

-

-    @Test

-    public void testConfiguration3() {

-        // Check the availability of CheckService

-        String name = "HandlerTest-2-empty";

-        ServiceReference sr = null;

-        ServiceReference[] refs = null;

-        String filter = "("+"instance.name"+"="+name+")";

-        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

-        if(refs != null) { sr = refs[0]; }

-        assertNotNull("Check the check service availability", sr);

-        

-        CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

-        Dictionary<String, Object> p = cs.getProps();

-        assertEquals("Assert 'simple' equality", p.get("Simple"), "Simple");

-        assertEquals("Size of p", 3, p.size()); // instance name, simple and changes.

-        

-        cs = null;

-    }

-

-    @Test

-	public void testLifecycle() {

-		// Check the availability of CheckService

-	    String name = "HandlerTest-1";

-        ServiceReference sr = null;

-        ServiceReference[] refs = null;

-        String filter = "("+"instance.name"+"="+name+")";

-        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

-        if(refs != null) { sr = refs[0]; }

-		assertNotNull("Check the check service availability", sr);

-		

-		ServiceReference sr_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "HandlerTest-1");

-		Architecture arch = (Architecture) osgiHelper.getServiceObject(sr_arch);

-		

-		assertEquals("Check instance validity - 0", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

-		

-		CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

-		Dictionary<String, Object> p = cs.getProps();

-		Integer changes = (Integer) p.get("changes");

-		assertNotNull("Check changes no null", changes);

-		assertEquals("Changes changes 1 ("+changes+")", changes.intValue(), 1);

-		assertEquals("Check instance validity - 1", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

-		cs.check();

-		p = cs.getProps();

-		changes = (Integer) p.get("changes");

-		assertEquals("Changes changes 2 ("+changes+")", changes.intValue(), 2);

-		assertEquals("Check instance validity - 2", arch.getInstanceDescription().getState(), ComponentInstance.INVALID);

-		cs.check();

-		p = cs.getProps();

-		changes = (Integer) p.get("changes");

-		assertEquals("Changes changes 3 ("+changes+")", changes.intValue(), 3);

-		assertEquals("Check instance validity - 3", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

-		cs.check();

-		p = cs.getProps();

-		changes = (Integer) p.get("changes");

-		assertEquals("Changes changes 4 ("+changes+")", changes.intValue(), 4);

-		assertEquals("Check instance validity - 4", arch.getInstanceDescription().getState(), ComponentInstance.INVALID);

-	}

-

-    @Test

-	public void testAvailability() {

-	    String name = "HandlerTest-1";

-        ServiceReference sr = null;

-        ServiceReference[] refs = null;

-        String filter = "("+"instance.name"+"="+name+")";

-        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

-

-        if(refs != null) { sr = refs[0]; }

-        assertNotNull("Check the check service availability", sr);

-        

-        ServiceReference sr_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "HandlerTest-1");

-        Architecture arch = (Architecture) osgiHelper.getServiceObject(sr_arch);

-        assertEquals("Check validity", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

-        

-        // Kill the handler factory

-        HandlerManagerFactory f = (HandlerManagerFactory)ipojoHelper.getHandlerFactory( "check");

-        f.stop();

-        

-        sr = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), "HandlerTest-1");

-        assertNull("Check the check service unavailability", sr);

-        

-        sr_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "HandlerTest-1");

-        assertNull("Check the architecture unavailability", sr_arch);

-        

-        // The instance is disposed, restart the handler

-        f.start();

-        

+    public void setUp() {

         Properties props = new Properties();

-        props.put("instance.name","HandlerTest-1");

+        props.put("instance.name", "HandlerTest-1");

         props.put("csh.simple", "simple");

         Properties p = new Properties();

         p.put("a", "a");

@@ -193,13 +49,163 @@
         p.put("c", "c");

         props.put("csh.map", p);

         instance = ipojoHelper.createComponentInstance("HANDLER-HandlerTester", props);

-        

+    }

+

+    @Test

+    public void testConfiguration1() {

+        // Check the availability of CheckService

+        String name = "HandlerTest-1";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "(" + "instance.name" + "=" + name + ")";

+        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

+        if (refs != null) {

+            sr = refs[0];

+        }

+

+        assertNotNull("Check the check service availability", sr);

+

+        CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

+        Dictionary<String, Object> p = cs.getProps();

+        assertEquals("Assert 'simple' equality", p.get("Simple"), "simple");

+        assertEquals("Assert 'a' equality", p.get("Map1"), "a");

+        assertEquals("Assert 'b' equality", p.get("Map2"), "b");

+        assertEquals("Assert 'c' equality", p.get("Map3"), "c");

+    }

+

+    @Test

+    public void testConfiguration2() {

+        // Check the availability of CheckService

+        String name = "HandlerTest-2";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "(" + "instance.name" + "=" + name + ")";

+

+        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

+

+        if (refs != null) {

+            sr = refs[0];

+        }

+        assertNotNull("Check the check service availability", sr);

+

+        CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

+        Dictionary<String, Object> p = cs.getProps();

+        assertEquals("Assert 'simple' equality", p.get("Simple"), "Simple");

+        assertEquals("Assert 'a' equality", p.get("Map1"), "a");

+        assertEquals("Assert 'b' equality", p.get("Map2"), "b");

+        assertEquals("Assert 'c' equality", p.get("Map3"), "c");

+    }

+

+    @Test

+    public void testConfiguration3() {

+        // Check the availability of CheckService

+        String name = "HandlerTest-2-empty";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "(" + "instance.name" + "=" + name + ")";

+        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

+        if (refs != null) {

+            sr = refs[0];

+        }

+        assertNotNull("Check the check service availability", sr);

+

+        CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

+        Dictionary<String, Object> p = cs.getProps();

+        assertEquals("Assert 'simple' equality", p.get("Simple"), "Simple");

+        assertEquals("Size of p", 3, p.size()); // instance name, simple and changes.

+

+        cs = null;

+    }

+

+    @Test

+    public void testLifecycle() {

+        // Check the availability of CheckService

+        String name = "HandlerTest-1";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "(" + "instance.name" + "=" + name + ")";

+        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

+        if (refs != null) {

+            sr = refs[0];

+        }

+        assertNotNull("Check the check service availability", sr);

+

+        ServiceReference sr_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "HandlerTest-1");

+        Architecture arch = (Architecture) osgiHelper.getServiceObject(sr_arch);

+

+        System.out.println("===");

+        Dumps.dumpArchitectures(context);

+        assertEquals("Check instance validity - 0", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+

+        CheckService cs = (CheckService) osgiHelper.getServiceObject(sr);

+        Dictionary<String, Object> p = cs.getProps();

+        Integer changes = (Integer) p.get("changes");

+        assertNotNull("Check changes no null", changes);

+        assertEquals("Changes changes 1 (" + changes + ")", changes.intValue(), 1);

+        assertEquals("Check instance validity - 1", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+        cs.check();

+        p = cs.getProps();

+        changes = (Integer) p.get("changes");

+        assertEquals("Changes changes 2 (" + changes + ")", changes.intValue(), 2);

+        assertEquals("Check instance validity - 2", arch.getInstanceDescription().getState(), ComponentInstance.INVALID);

+        cs.check();

+        p = cs.getProps();

+        changes = (Integer) p.get("changes");

+        assertEquals("Changes changes 3 (" + changes + ")", changes.intValue(), 3);

+        assertEquals("Check instance validity - 3", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+        cs.check();

+        p = cs.getProps();

+        changes = (Integer) p.get("changes");

+        assertEquals("Changes changes 4 (" + changes + ")", changes.intValue(), 4);

+        assertEquals("Check instance validity - 4", arch.getInstanceDescription().getState(), ComponentInstance.INVALID);

+    }

+

+    @Test

+    public void testAvailability() {

+        String name = "HandlerTest-1";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "(" + "instance.name" + "=" + name + ")";

+        refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter);

+

+        if (refs != null) {

+            sr = refs[0];

+        }

+        assertNotNull("Check the check service availability", sr);

+

+        ServiceReference sr_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "HandlerTest-1");

+        Architecture arch = (Architecture) osgiHelper.getServiceObject(sr_arch);

+        assertEquals("Check validity", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+

+        // Kill the handler factory

+        HandlerManagerFactory f = (HandlerManagerFactory) ipojoHelper.getHandlerFactory("check");

+        f.stop();

+

+        sr = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), "HandlerTest-1");

+        assertNull("Check the check service unavailability", sr);

+

+        sr_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "HandlerTest-1");

+        assertNull("Check the architecture unavailability", sr_arch);

+

+        // The instance is disposed, restart the handler

+        f.start();

+

+        Properties props = new Properties();

+        props.put("instance.name", "HandlerTest-1");

+        props.put("csh.simple", "simple");

+        Properties p = new Properties();

+        p.put("a", "a");

+        p.put("b", "b");

+        p.put("c", "c");

+        props.put("csh.map", p);

+        instance = ipojoHelper.createComponentInstance("HANDLER-HandlerTester", props);

+

         sr = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), "HandlerTest-1");

         assertNotNull("Check the check service availability - 2", sr);

-        

+

         sr_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "HandlerTest-1");

         arch = (Architecture) osgiHelper.getServiceObject(sr_arch);

         assertEquals("Check validity - 2", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

-	}

+    }

 

 }

diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java b/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java
index cca2615..53bebb1 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java
@@ -95,7 +95,7 @@
         assertNotNull("Check factory availability -2", cf);

         assertEquals("Check factory state -2", Factory.INVALID, cf.getState());

 

-        // Check the instance disappearance

+        // Check the instance disappearance, the instance was disposed.

         ref_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "SimpleInstance");

         assertNull("Check Architecture availability -1", ref_arch);

 

@@ -113,7 +113,5 @@
         // Check the instance re-creation

         ref_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "SimpleInstance");

         assertNotNull("Check Architecture availability -3", ref_arch);

-

     }

-

 }

diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java b/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java
index 5305cf2..fd54099 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java
@@ -97,9 +97,9 @@
         // Wait for the processing of the first configuration.
         grace();
 
-        Assert.assertNull("No architecture", osgiHelper.getServiceReference(Architecture.class.getName(),
-                "(architecture.instance=" + pid + ")"));
-
+        // Due to change in Architecture, the architecture service is still exposed but the instance state is STOPPED.
+        // This was made to ease debugging to dead instances.
+        Assert.assertTrue(ipojoHelper.isInstanceStopped(pid));
 
         // Reconfigure
         props = new Properties();
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index 11d3711..8aff8c5 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -179,11 +179,13 @@
             return instance;
         } catch (ConfigurationException e) {
             // An exception occurs while executing the configure or start
-            // methods.
-            instance.dispose();
+            // methods, the instance is stopped so the architecture service is still published and so we can debug
+            // the issue.
+            instance.stop();
             throw e;
         } catch (Throwable e) { // All others exception are handled here.
-            instance.dispose();
+            // As for the previous case, the instance is stopped.
+            instance.stop();
             m_logger.log(Logger.ERROR, e.getMessage(), e);
             throw new ConfigurationException(e.getMessage(), e);
         }
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index 3cabe83..cdce659 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -468,7 +468,7 @@
      */
     public void dispose() {
         List listeners = null;
-        int state = -2; // Temporary state
+        int state; // Will be confined in stack.
         synchronized (this) {
             state = m_state; // Stack confinement
             if (m_listeners != null) {
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java
index db23941..424e8fd 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java
@@ -27,6 +27,11 @@
 public interface Architecture {
 
     /**
+     * Architecture service must published this property telling which instance they are representing.
+     */
+    public static final String ARCHITECTURE_INSTANCE = "architecture.instance";
+
+    /**
      * Returns the description of the instance.
      * @return the component instance description
      */
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
index 632722c..740689e 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
@@ -189,7 +189,7 @@
      * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
      */
     public synchronized void stateChanged(ComponentInstance instance, int newState) {
-        notifyAll(); // if we was in a transition, the transition is now done.
+        notifyAll(); // if we were in a transition, the transition has completed.
     }
 
 }
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
index dc32dc9..e8cce04 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -18,37 +18,57 @@
  */
 package org.apache.felix.ipojo.handlers.architecture;
 
-import java.util.Dictionary;
-
+import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.InstanceStateListener;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.ServiceRegistration;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
 
 /**
- * Architecture Handler : do reflection on your component.
+ * Architecture Handler. Provide a runtime representation of iPOJO instances.
+ *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ArchitectureHandler extends PrimitiveHandler implements Architecture {
+public class ArchitectureHandler extends PrimitiveHandler implements Architecture, InstanceStateListener {
 
     /**
      * Name of the component.
      */
     private String m_name;
+    /**
+     * The Architecture service registration.
+     */
+    private ServiceRegistration m_serviceRegistration;
 
     /**
      * Configure the handler.
-     * @param metadata : the metadata of the component
+     *
+     * @param metadata      : the metadata of the component
      * @param configuration : the instance configuration
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
     public void configure(Element metadata, Dictionary configuration) {
         m_name = (String) configuration.get(Factory.INSTANCE_NAME_PROPERTY);
+        Dictionary<String, String> dict = new Hashtable<String, String>();
+        dict.put(ARCHITECTURE_INSTANCE, m_name);
+
+        debug("Registering architecture service for " + m_name);
+        m_serviceRegistration = getInstanceManager().getContext().registerService(Architecture.class.getName(), this, dict);
+
+        // We can't use the regular handler stateChanged method as this method is not called when the instance is
+        // disposed. This handler stays actives until the instance disposal.
+        getInstanceManager().addInstanceStateListener(this);
     }
 
     /**
      * Stop method.
+     *
      * @see org.apache.felix.ipojo.Handler#stop()
      */
     public void stop() {
@@ -57,18 +77,35 @@
 
     /**
      * Start method.
+     *
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-        debug("Start architecture handler with " + m_name + " name");
+        // Nothing to do.
     }
 
     /**
      * Get the instance description.
+     *
      * @return the instance description
      * @see org.apache.felix.ipojo.architecture.Architecture#getInstanceDescription()
      */
     public InstanceDescription getInstanceDescription() {
         return getInstanceManager().getInstanceDescription();
     }
+
+    /**
+     * The instance lifecycle listener callback.
+     * When we receive the DISPOSED state, the architecture is unregistered from the service registry.
+     *
+     * @param instance the changing instance the instance, meaningless in our case.
+     * @param newState the new instance state the new instance state.
+     */
+    public void stateChanged(ComponentInstance instance, int newState) {
+        if (newState == ComponentInstance.DISPOSED && m_serviceRegistration != null) {
+            debug("Withdrawing the architecture service of " + m_name + " due to instance disposal");
+            m_serviceRegistration.unregister();
+            m_serviceRegistration = null;
+        }
+    }
 }
diff --git a/ipojo/runtime/core/src/main/resources/metadata.xml b/ipojo/runtime/core/src/main/resources/metadata.xml
index beeeeaf..a367d5a 100644
--- a/ipojo/runtime/core/src/main/resources/metadata.xml
+++ b/ipojo/runtime/core/src/main/resources/metadata.xml
@@ -40,8 +40,6 @@
     <handler

             classname="org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler"

             name="architecture" architecture="false">

-        <provides specifications="org.apache.felix.ipojo.architecture.Architecture">

-            <property field="m_name" name="architecture.instance"/>

-        </provides>

+            <!-- The architecture service is published by the handler manually -->

     </handler>

 </ipojo>
\ No newline at end of file