Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 60AD51078D for ; Wed, 8 May 2013 16:52:05 +0000 (UTC) Received: (qmail 86457 invoked by uid 500); 8 May 2013 16:52:02 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 85630 invoked by uid 500); 8 May 2013 16:52:01 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 85495 invoked by uid 99); 8 May 2013 16:52:01 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 May 2013 16:52:01 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 May 2013 16:51:54 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 99FDA2388993; Wed, 8 May 2013 16:51:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1480353 - in /felix/trunk/ipojo: arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/ runtime/api-it/ runtime/composite-it/ runtime/composite-it/src/it/ipojo-composite-import-export-test/ runtime/composite-it/src/it/ipojo-composite-ru... Date: Wed, 08 May 2013 16:51:30 -0000 To: commits@felix.apache.org From: clement@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130508165131.99FDA2388993@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: clement Date: Wed May 8 16:51:29 2013 New Revision: 1480353 URL: http://svn.apache.org/r1480353 Log: 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) Modified: felix/trunk/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java felix/trunk/ipojo/runtime/api-it/pom.xml felix/trunk/ipojo/runtime/composite-it/pom.xml felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java felix/trunk/ipojo/runtime/composite/src/main/resources/metadata.xml felix/trunk/ipojo/runtime/core-it/pom.xml felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java felix/trunk/ipojo/runtime/core/src/main/resources/metadata.xml Modified: felix/trunk/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java (original) +++ felix/trunk/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java Wed May 8 16:51:29 2013 @@ -20,6 +20,7 @@ package org.apache.felix.ipojo.arch.gogo 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 @@ public class Arch { @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 @@ public class Arch { */ @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 @@ public class Arch { 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 { Modified: felix/trunk/ipojo/runtime/api-it/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/api-it/pom.xml?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/api-it/pom.xml (original) +++ felix/trunk/ipojo/runtime/api-it/pom.xml Wed May 8 16:51:29 2013 @@ -195,6 +195,12 @@ org.apache.felix.ipojo.handler.whiteboard 1.4.0 test + + + org.apache.felix + org.osgi.core + + Modified: felix/trunk/ipojo/runtime/composite-it/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite-it/pom.xml?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite-it/pom.xml (original) +++ felix/trunk/ipojo/runtime/composite-it/pom.xml Wed May 8 16:51:29 2013 @@ -205,6 +205,12 @@ osgi-helpers 0.6.1-SNAPSHOT test + + + org.osgi + org.osgi.core + + @@ -388,7 +394,7 @@ org.osgi org.osgi.core 4.3.1 - provided + compile Modified: felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml (original) +++ felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-import-export-test/pom.xml Wed May 8 16:51:29 2013 @@ -31,7 +31,6 @@ 4.0.0 - org.apache.felix ipojo-composite-import-export-test ${project.artifactId} Modified: felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java (original) +++ felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-runtime-test/src/test/java/org/apache/felix/ipojo/runtime/core/EmptyCompositeTest.java Wed May 8 16:51:29 2013 @@ -88,7 +88,8 @@ public class EmptyCompositeTest extends 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()); } Modified: felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java (original) +++ felix/trunk/ipojo/runtime/composite-it/src/it/ipojo-composite-service-providing-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java Wed May 8 16:51:29 2013 @@ -26,6 +26,9 @@ import org.ops4j.pax.exam.spi.reactors.E 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 class Common extends BaseTest { public boolean deployiPOJOComposite() { return true; } + + @Override + protected List getExtraExports() { + return Arrays.asList( + "org.apache.felix.ipojo.runtime.core.components" + ); + } } Modified: felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java (original) +++ felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java Wed May 8 16:51:29 2013 @@ -50,7 +50,7 @@ public class CompositeInstanceDescriptio /** - * 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 @@ public class CompositeInstanceDescriptio // 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 Modified: felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java (original) +++ felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java Wed May 8 16:51:29 2013 @@ -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 Felix Project Team */ -public class ArchitectureHandler extends CompositeHandler implements Architecture { +public class ArchitectureHandler extends CompositeHandler implements Architecture, InstanceStateListener { /** * Name of the component. @@ -38,37 +43,66 @@ public class ArchitectureHandler extends 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 dict = new Hashtable(); + 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 to do. + // Nothing do do when stopping. } /** - * Start the handler. + * Start method. + * * @see org.apache.felix.ipojo.Handler#start() */ - public void start() { - info("Start composite architecture handler with " + m_name + " name"); + public void start() { + // Nothing to do. + } + + /** + * 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; + } } /** * 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(); Modified: felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java (original) +++ felix/trunk/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java Wed May 8 16:51:29 2013 @@ -197,7 +197,8 @@ public class InstanceHandler extends Com 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 @@ public class InstanceHandler extends Com /** * 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 class InstanceHandler extends Com 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 @@ public class InstanceHandler extends Com 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; } } Modified: felix/trunk/ipojo/runtime/composite/src/main/resources/metadata.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/composite/src/main/resources/metadata.xml?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/composite/src/main/resources/metadata.xml (original) +++ felix/trunk/ipojo/runtime/composite/src/main/resources/metadata.xml Wed May 8 16:51:29 2013 @@ -38,8 +38,6 @@ - - - + \ No newline at end of file Modified: felix/trunk/ipojo/runtime/core-it/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/pom.xml?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core-it/pom.xml (original) +++ felix/trunk/ipojo/runtime/core-it/pom.xml Wed May 8 16:51:29 2013 @@ -211,6 +211,12 @@ osgi-helpers 0.6.1-SNAPSHOT test + + + org.osgi + org.osgi.core + + @@ -395,7 +401,7 @@ org.osgi org.osgi.core 4.3.1 - provided + compile Modified: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java (original) +++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestArchitecture.java Wed May 8 16:51:29 2013 @@ -29,8 +29,7 @@ import org.junit.Test; 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 @@ public class TestArchitecture extends Co */ ComponentInstance instance2; - /** - * Instance without configuration. - */ - ComponentInstance instance3; - @Before public void setUp() { String type = "CONFIG-FooProviderType-4"; @@ -118,5 +112,35 @@ public class TestArchitecture extends Co } + /** + * 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); + } + } Modified: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java (original) +++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-external-handlers-test/src/test/java/org/apache/felix/ipojo/runtime/externalhandlers/test/HandlerTest.java Wed May 8 16:51:29 2013 @@ -22,10 +22,10 @@ import org.apache.felix.ipojo.ComponentI 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,67 +36,65 @@ import static org.junit.Assert.assertNul 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; - } + 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); + } @Test - public void testConfiguration1() { - // Check the availability of CheckService - String name = "HandlerTest-1"; - ServiceReference sr = null; - ServiceReference[] refs = null; - String filter = "("+"instance.name"+"="+name+")"; + 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 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"); - } + if (refs != null) { + sr = refs[0]; + } + + assertNotNull("Check the check service availability", sr); + + CheckService cs = (CheckService) osgiHelper.getServiceObject(sr); + Dictionary 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"; + public void testConfiguration2() { + // Check the availability of CheckService + String name = "HandlerTest-2"; ServiceReference sr = null; ServiceReference[] refs = null; - String filter = "("+"instance.name"+"="+name+")"; + 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); + if (refs != null) { + sr = refs[0]; + } + assertNotNull("Check the check service availability", sr); + + CheckService cs = (CheckService) osgiHelper.getServiceObject(sr); Dictionary 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"); - } + 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() { @@ -104,88 +102,96 @@ public class HandlerTest extends Common String name = "HandlerTest-2-empty"; ServiceReference sr = null; ServiceReference[] refs = null; - String filter = "("+"instance.name"+"="+name+")"; + String filter = "(" + "instance.name" + "=" + name + ")"; refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter); - if(refs != null) { sr = refs[0]; } + if (refs != null) { + sr = refs[0]; + } assertNotNull("Check the check service availability", sr); - + CheckService cs = (CheckService) osgiHelper.getServiceObject(sr); Dictionary 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"; + public void testLifecycle() { + // Check the availability of CheckService + String name = "HandlerTest-1"; ServiceReference sr = null; ServiceReference[] refs = null; - String filter = "("+"instance.name"+"="+name+")"; + 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 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); - } + 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 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"; + public void testAvailability() { + String name = "HandlerTest-1"; ServiceReference sr = null; ServiceReference[] refs = null; - String filter = "("+"instance.name"+"="+name+")"; + String filter = "(" + "instance.name" + "=" + name + ")"; refs = osgiHelper.getServiceReferences(CheckService.class.getName(), filter); - if(refs != null) { sr = refs[0]; } + 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"); + 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("instance.name", "HandlerTest-1"); props.put("csh.simple", "simple"); Properties p = new Properties(); p.put("a", "a"); @@ -193,13 +199,13 @@ public class HandlerTest extends Common 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); - } + } } Modified: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java (original) +++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestObedience.java Wed May 8 16:51:29 2013 @@ -95,7 +95,7 @@ public class TestObedience extends Commo 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 @@ public class TestObedience extends Commo // Check the instance re-creation ref_arch = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), "SimpleInstance"); assertNotNull("Check Architecture availability -3", ref_arch); - } - } Modified: felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java (original) +++ felix/trunk/ipojo/runtime/core-it/src/it/ipojo-core-factory-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestReconfiguration.java Wed May 8 16:51:29 2013 @@ -97,9 +97,9 @@ public class TestReconfiguration extends // 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(); Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java (original) +++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java Wed May 8 16:51:29 2013 @@ -179,11 +179,13 @@ public class ComponentFactory extends IP 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); } Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java (original) +++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java Wed May 8 16:51:29 2013 @@ -468,7 +468,7 @@ public class InstanceManager implements */ 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) { Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java (original) +++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java Wed May 8 16:51:29 2013 @@ -27,6 +27,11 @@ package org.apache.felix.ipojo.architect 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 */ Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java (original) +++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java Wed May 8 16:51:29 2013 @@ -189,7 +189,7 @@ public class InstanceDescription impleme * @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. } } Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java (original) +++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java Wed May 8 16:51:29 2013 @@ -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 Felix Project Team */ -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 dict = new Hashtable(); + 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 @@ public class ArchitectureHandler extends /** * 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; + } + } } Modified: felix/trunk/ipojo/runtime/core/src/main/resources/metadata.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/resources/metadata.xml?rev=1480353&r1=1480352&r2=1480353&view=diff ============================================================================== --- felix/trunk/ipojo/runtime/core/src/main/resources/metadata.xml (original) +++ felix/trunk/ipojo/runtime/core/src/main/resources/metadata.xml Wed May 8 16:51:29 2013 @@ -40,8 +40,6 @@ - - - + \ No newline at end of file