You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2013/09/30 11:34:36 UTC

svn commit: r1527496 [1/2] - in /felix/trunk/ipojo/runtime: core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/ core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apa...

Author: clement
Date: Mon Sep 30 09:34:36 2013
New Revision: 1527496

URL: http://svn.apache.org/r1527496
Log:
Improve configuration error detection and reporting of service dependency (FELIX-4243 Define the dependency configuration matrix and improve error detection)
Added test about FELIX-4250 Specification deduction broken when the method does not start with the 'bind' prefix

Added:
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/identification/
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/identification/ComponentWithCustomMethods.java
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/identification/
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/identification/TestDependencyIdDetection.java
      - copied, changed from r1527464, felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/filter/TestFromDependencies.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/AggregateDependencyInjectionType.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyConfigurationChecker.java
Modified:
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/CheckServiceProvider.java
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/exceptions/ExceptionAwareCheckServiceProvider.java
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/context/ContextualFilterConsumer.java
    felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/Common.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/handlers/dependency/Dependency.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ProxyGenerator.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceCollection.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java

Modified: felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/CheckServiceProvider.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/CheckServiceProvider.java?rev=1527496&r1=1527495&r2=1527496&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/CheckServiceProvider.java (original)
+++ felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/CheckServiceProvider.java Mon Sep 30 09:34:36 2013
@@ -45,28 +45,28 @@ public class CheckServiceProvider extend
 
     public Properties getProps() {
         Properties props = new Properties();
-        props.put("voidB", new Integer(simpleB));
-        props.put("objectB", new Integer(objectB));
-        props.put("refB", new Integer(refB));
-        props.put("bothB", new Integer(bothB));
-        props.put("voidU", new Integer(simpleU));
-        props.put("objectU", new Integer(objectU));
-        props.put("refU", new Integer(refU));
-        props.put("bothU", new Integer(bothU));
-        props.put("mapB", new Integer(mapB));
-        props.put("dictB", new Integer(dictB));
-        props.put("mapU", new Integer(mapU));
-        props.put("dictU", new Integer(dictU));
+        props.put("voidB", simpleB);
+        props.put("objectB", objectB);
+        props.put("refB", refB);
+        props.put("bothB", bothB);
+        props.put("voidU", simpleU);
+        props.put("objectU", objectU);
+        props.put("refU", refU);
+        props.put("bothU", bothU);
+        props.put("mapB", mapB);
+        props.put("dictB", dictB);
+        props.put("mapU", mapU);
+        props.put("dictU", dictU);
         if (fs != null) {
             // If nullable = false and proxy, a runtime exception may be launched here
             // catch the exception and add this to props.
             try {
                 props.put("exception", Boolean.FALSE); // Set exception to false for checking.
-                props.put("result", new Boolean(fs.foo()));
-                props.put("boolean", new Boolean(fs.getBoolean()));
-                props.put("int", new Integer(fs.getInt()));
-                props.put("long", new Long(fs.getLong()));
-                props.put("double", new Double(fs.getDouble()));
+                props.put("result", fs.foo());
+                props.put("boolean", fs.getBoolean());
+                props.put("int", fs.getInt());
+                props.put("long", fs.getLong());
+                props.put("double", fs.getDouble());
                 if(fs.getObject() != null) { props.put("object", fs.getObject()); }
             } catch (RuntimeException e) {
                 props.put("exception", Boolean.TRUE);
@@ -77,7 +77,7 @@ public class CheckServiceProvider extend
         
         
         // Add modified
-        props.put("modified", new Integer(modified));
+        props.put("modified", modified);
         
         return props;
     }
@@ -95,7 +95,7 @@ public class CheckServiceProvider extend
             System.err.println("Bind receive null !!! ");
             return;
         }
-        if(o != null && o instanceof FooService) { objectB++; }
+        objectB++;
     }
     
     protected void objectModify(FooService o) {
@@ -103,7 +103,7 @@ public class CheckServiceProvider extend
             System.err.println("Bind receive null !!! [" + modified + "]");
             return;
         }
-        if(o != null && o instanceof FooService) { modified++; }
+        modified++;
     }
     
     public void refBind(ServiceReference sr) {
@@ -115,30 +115,30 @@ public class CheckServiceProvider extend
     }
     
     public void bothBind(FooService o, ServiceReference sr) {
-        if(sr != null && o != null && o instanceof FooService) { bothB++; }
+        if(sr != null && o != null) { bothB++; }
     }
     
     public void bothModify(FooService o, ServiceReference sr) {
-        if(sr != null && o != null && o instanceof FooService) { modified++; }
+        if(sr != null && o != null) { modified++; }
     }
     
     protected void propertiesDictionaryBind(FooService o, Dictionary props) {
-        if(props != null && o != null && o instanceof FooService && props.size() > 0) { dictB++; }
+        if(props != null && o != null && props.size() > 0) { dictB++; }
         fs = o;
     }   
     
     protected void propertiesDictionaryModify(FooService o, Dictionary props) {
-        if(props != null && o != null && o instanceof FooService && props.size() > 0) { modified++; }
+        if(props != null && o != null && props.size() > 0) { modified++; }
         fs = o;
     }   
     
     protected void propertiesMapBind(FooService o, Map props) {
-        if(props != null && o != null && o instanceof FooService && props.size() > 0) { mapB++; }
+        if(props != null && o != null && props.size() > 0) { mapB++; }
         fs = o;
     } 
     
     protected void propertiesMapModify(FooService o, Map props) {
-        if(props != null && o != null && o instanceof FooService && props.size() > 0) { modified++; }
+        if(props != null && o != null && props.size() > 0) { modified++; }
         fs = o;
     } 
 

Modified: felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/exceptions/ExceptionAwareCheckServiceProvider.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/exceptions/ExceptionAwareCheckServiceProvider.java?rev=1527496&r1=1527495&r2=1527496&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/exceptions/ExceptionAwareCheckServiceProvider.java (original)
+++ felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-optional-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/exceptions/ExceptionAwareCheckServiceProvider.java Mon Sep 30 09:34:36 2013
@@ -59,7 +59,7 @@ public class ExceptionAwareCheckServiceP
             fs.foo();
             return true; // always return true, to detect the exception case.
         } catch (NoServiceException e) {
-            return true;
+            return false;
         }
     }
 

Modified: felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/context/ContextualFilterConsumer.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/context/ContextualFilterConsumer.java?rev=1527496&r1=1527495&r2=1527496&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/context/ContextualFilterConsumer.java (original)
+++ felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/context/ContextualFilterConsumer.java Mon Sep 30 09:34:36 2013
@@ -36,7 +36,7 @@ import java.util.Properties;
 @Provides
 public class ContextualFilterConsumer implements CheckService {
 
-    @Requires(nullable = false, id = "foo")
+    @Requires(id = "foo")
     private FooService foo;
 
     @Override

Added: felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/identification/ComponentWithCustomMethods.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/identification/ComponentWithCustomMethods.java?rev=1527496&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/identification/ComponentWithCustomMethods.java (added)
+++ felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/components/identification/ComponentWithCustomMethods.java Mon Sep 30 09:34:36 2013
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.components.identification;
+
+import org.apache.felix.ipojo.annotations.Bind;
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Unbind;
+import org.apache.felix.ipojo.runtime.core.test.services.Call;
+import org.apache.felix.ipojo.runtime.core.test.services.FooService;
+
+import java.util.Set;
+
+/**
+ * A component reproducing FELIX-4250 - Specification deduction broken when the method does not start with the 'bind'
+ * prefix (https://issues.apache.org/jira/browse/FELIX-4250).
+ *
+ * The add and remove methods should be attached to the same dependency (id = MyService)
+ * The set and unset methods should be attached to the same dependency (id = MyOtherService)
+ */
+@Component
+public class ComponentWithCustomMethods {
+
+    Set<FooService> myServices;
+
+    Set<Call> myOtherServices;
+
+    @Bind(optional=true, aggregate=true)
+    public void addMyService(FooService newService) {
+        myServices.add(newService);
+    }
+
+    @Unbind
+    public void removeMyService(FooService oldService) {
+        myServices.remove(oldService);
+    }
+
+
+    @Bind(optional=true, aggregate=true)
+    public void setMyOtherService(Call newService) {
+        myOtherServices.add(newService);
+    }
+
+    @Unbind
+    public void unsetMyOtherService(Call oldService) {
+        myOtherServices.remove(oldService);
+    }
+}

Modified: felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/Common.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/Common.java?rev=1527496&r1=1527495&r2=1527496&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/Common.java (original)
+++ felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/Common.java Mon Sep 30 09:34:36 2013
@@ -19,11 +19,16 @@
 
 package org.apache.felix.ipojo.runtime.core.test.dependencies;
 
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
 import org.ow2.chameleon.testing.helpers.BaseTest;
 
 import java.util.Arrays;
 import java.util.List;
 
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+
 /**
  * Bootstrap the test from this project
  */
@@ -36,4 +41,12 @@ public class Common extends BaseTest {
         );
     }
 
+    @Override
+    protected Option[] getCustomOptions() {
+        return new Option[] {
+                wrappedBundle(maven("org.easytesting", "fest-assert").versionAsInProject()),
+                wrappedBundle(maven("org.easytesting", "fest-util").versionAsInProject())
+        };
+    }
+
 }

Copied: felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/identification/TestDependencyIdDetection.java (from r1527464, felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/filter/TestFromDependencies.java)
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/identification/TestDependencyIdDetection.java?p2=felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/identification/TestDependencyIdDetection.java&p1=felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/filter/TestFromDependencies.java&r1=1527464&r2=1527496&rev=1527496&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/filter/TestFromDependencies.java (original)
+++ felix/trunk/ipojo/runtime/core-it/ipojo-core-service-dependency-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/identification/TestDependencyIdDetection.java Mon Sep 30 09:34:36 2013
@@ -16,304 +16,92 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.ipojo.runtime.core.test.dependencies.filter;
+
+package org.apache.felix.ipojo.runtime.core.test.dependencies.identification;
 
 import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.annotations.HandlerDeclaration;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.handlers.dependency.DependencyCallback;
+import org.apache.felix.ipojo.handlers.dependency.DependencyDescription;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandlerDescription;
 import org.apache.felix.ipojo.runtime.core.test.dependencies.Common;
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
-import org.osgi.framework.ServiceReference;
-
-import java.util.Properties;
-
-import static org.junit.Assert.*;
 
-public class TestFromDependencies extends Common {
-
-    ComponentInstance instance1, instance2, instance3, instance4;
-    ComponentInstance providerA, providerB, providerC, providerD;
-
-    @Before
-    public void setUp() {
-        try {
-            Properties prov = new Properties();
-            prov.put("instance.name", "A");
-            providerA = ipojoHelper.getFactory("SimpleFilterCheckServiceProvider").createComponentInstance(prov);
-            providerA.stop();
-
-            Properties prov2 = new Properties();
-            prov2.put("instance.name", "B");
-            providerB = ipojoHelper.getFactory("SimpleFilterCheckServiceProvider").createComponentInstance(prov2);
-            providerB.stop();
-
-            Properties prov3 = new Properties();
-            prov3.put("service.pid", "A");
-            providerC = ipojoHelper.getFactory("SimplePIDCheckServiceProvider").createComponentInstance(prov3);
-            providerC.stop();
-
-            Properties prov4 = new Properties();
-            prov4.put("service.pid", "D");
-            prov4.put("instance.name", "D");
-            providerD = ipojoHelper.getFactory("SimplePIDCheckServiceProvider").createComponentInstance(prov4);
-            providerD.stop();
-
-            // Uses the component type from value
-            Properties i1 = new Properties();
-            i1.put("instance.name", "Subscriber1");
-            instance1 = ipojoHelper.getFactory("SimpleFromCheckServiceSubscriber").createComponentInstance(i1);
-
-            // Uses the instance configuration from value
-            Properties i2 = new Properties();
-            i2.put("instance.name", "Subscriber2");
-            Properties ii2 = new Properties();
-            ii2.put("id1", "B");
-            i2.put("requires.from", ii2);
-            instance2 = ipojoHelper.getFactory("SimpleFromCheckServiceSubscriber").createComponentInstance(i2);
-
-            // Uses the instance configuration from value (*)
-            Properties i3 = new Properties();
-            i3.put("instance.name", "Subscriber3");
-            Properties ii3 = new Properties();
-            ii3.put("id1", "*");
-            i3.put("requires.from", ii3);
-            instance3 = ipojoHelper.getFactory("SimpleFromCheckServiceSubscriber").createComponentInstance(i3);
-
-            // Uses the instance configuration from value, merge filter and from
-            Properties i4 = new Properties();
-            i4.put("instance.name", "Subscriber4");
-            Properties ii4 = new Properties();
-            ii4.put("id1", "D");
-            i4.put("requires.from", ii4);
-            Properties iii4 = new Properties();
-            iii4.put("id1", "(service.pid=D)");
-            i4.put("requires.filters", iii4);
-            instance4 = ipojoHelper.getFactory("SimpleFromCheckServiceSubscriber").createComponentInstance(i4);
-
-        } catch (Exception e) {
-            e.printStackTrace();
-            fail(e.getMessage());
-        }
-
-    }
-
-    @After
-    public void tearDown() {
-        instance1.dispose();
-        instance2.dispose();
-        instance3.dispose();
-        instance4.dispose();
-        providerA.dispose();
-        providerB.dispose();
-        providerC.dispose();
-        providerD.dispose();
-        instance1 = null;
-        instance2 = null;
-        instance3 = null;
-        instance4 = null;
-        providerA = null;
-        providerB = null;
-        providerC = null;
-        providerD = null;
-    }
+import static org.fest.assertions.Assertions.assertThat;
 
+public class TestDependencyIdDetection extends Common {
+    String factory = "org.apache.felix.ipojo.runtime.core.test.components.identification.ComponentWithCustomMethods";
 
     @Test
-    public void testFromInstanceName() {
-        instance1.start();
-
-        ServiceReference arch_ref = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), instance1.getInstanceName());
-        assertNotNull("Check architecture availability", arch_ref);
-        InstanceDescription id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);
-
-        providerB.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);
-
-        providerA.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);
-
-        providerA.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.INVALID);
-
-        providerA.start();
+    public void testSetAndUnSetMethods() {
+        ComponentInstance instance = ipojoHelper.createComponentInstance(factory);
+        DependencyHandlerDescription dh = (DependencyHandlerDescription) instance.getInstanceDescription()
+                .getHandlerDescription("org.apache.felix.ipojo:requires");
 
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);
+        DependencyDescription dd = findDependencyById(dh, "MyOtherService");
+        assertThat(dd).isNotNull();
 
+        DependencyCallback[] callbacks = dd.getDependency().getDependencyCallbacks();
+        assertThat(callbacks).isNotNull();
 
-        providerA.stop();
+        DependencyCallback bind = getBindCallback(callbacks);
+        DependencyCallback unbind = getUnbindCallback(callbacks);
 
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.INVALID);
+        assertThat(bind).isNotNull();
+        assertThat(unbind).isNotNull();
 
-        id = null;
-        providerB.stop();
-        getContext().ungetService(arch_ref);
+        assertThat(bind.getMethodName()).isEqualTo("setMyOtherService");
+        assertThat(unbind.getMethodName()).isEqualTo("unsetMyOtherService");
     }
 
     @Test
-    public void testFromPID() {
-        instance1.start();
+    public void testAddAndRemoveMethods() {
+        ComponentInstance instance = ipojoHelper.createComponentInstance(factory);
+        DependencyHandlerDescription dh = (DependencyHandlerDescription) instance.getInstanceDescription()
+                .getHandlerDescription("org.apache.felix.ipojo:requires");
 
-        ServiceReference arch_ref = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), instance1.getInstanceName());
-        assertNotNull("Check architecture availability", arch_ref);
-        InstanceDescription id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);
+        DependencyDescription dd = findDependencyById(dh, "MyService");
+        assertThat(dd).isNotNull();
 
-        providerB.start();
+        DependencyCallback[] callbacks = dd.getDependency().getDependencyCallbacks();
+        assertThat(callbacks).isNotNull();
 
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);
+        DependencyCallback bind = getBindCallback(callbacks);
+        DependencyCallback unbind = getUnbindCallback(callbacks);
 
-        providerC.start();
+        assertThat(bind).isNotNull();
+        assertThat(unbind).isNotNull();
 
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);
-
-        providerC.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.INVALID);
-
-        providerC.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);
-
-        providerC.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.INVALID);
-
-        id = null;
-        providerB.stop();
-        getContext().ungetService(arch_ref);
+        assertThat(bind.getMethodName()).isEqualTo("addMyService");
+        assertThat(unbind.getMethodName()).isEqualTo("removeMyService");
     }
 
-    @Test
-    public void testFromInstanceNameInstanceConfiguration() {
-        instance2.start();
-
-        ServiceReference arch_ref = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), instance2.getInstanceName());
-        assertNotNull("Check architecture availability", arch_ref);
-        InstanceDescription id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);
-
-        providerA.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);
-
-        providerB.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);
-
-        providerB.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.INVALID);
-
-        providerB.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);
-
-        providerB.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.INVALID);
-
-        id = null;
-        providerA.stop();
-        getContext().ungetService(arch_ref);
+    private DependencyCallback getBindCallback(DependencyCallback[] callbacks) {
+        for (DependencyCallback callback : callbacks) {
+            if (callback.getMethodType() == DependencyCallback.BIND) {
+                return callback;
+            }
+        }
+        return null;
     }
 
-    @Test
-    public void testFromInstanceNameStar() {
-        instance3.start();
-
-        ServiceReference arch_ref = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), instance3.getInstanceName());
-        assertNotNull("Check architecture availability", arch_ref);
-        InstanceDescription id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);
-
-        providerA.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 0", id.getState() == ComponentInstance.VALID);
-
-        providerB.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);
-
-        providerB.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.VALID);
-
-        providerA.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.INVALID);
-
-        providerB.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.VALID);
-
-        id = null;
-        providerB.stop();
-        getContext().ungetService(arch_ref);
+    private DependencyCallback getUnbindCallback(DependencyCallback[] callbacks) {
+        for (DependencyCallback callback : callbacks) {
+            if (callback.getMethodType() == DependencyCallback.UNBIND) {
+                return callback;
+            }
+        }
+        return null;
     }
 
-    @Test
-    public void testFromAndFilter() {
-        instance4.start();
-
-        ServiceReference arch_ref = ipojoHelper.getServiceReferenceByName(Architecture.class.getName(), instance4.getInstanceName());
-        assertNotNull("Check architecture availability", arch_ref);
-        InstanceDescription id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);
-
-        providerA.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);
-
-        providerD.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);
-
-        providerD.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.INVALID);
-
-        providerD.start();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);
-
-        providerD.stop();
-
-        id = ((Architecture) getContext().getService(arch_ref)).getInstanceDescription();
-        assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.INVALID);
-
-        id = null;
-        providerA.stop();
-        getContext().ungetService(arch_ref);
+    private DependencyDescription findDependencyById(DependencyHandlerDescription dh, String id) {
+        for (DependencyDescription dd : dh.getDependencies()) {
+            if (dd.getId().equals(id)) {
+                return dd;
+            }
+        }
+        return null;
     }
 
 

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=1527496&r1=1527495&r2=1527496&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 Mon Sep 30 09:34:36 2013
@@ -187,7 +187,7 @@ public class ComponentFactory extends IP
         } catch (Throwable e) { // All others exception are handled here.
             // As for the previous case, the instance is stopped.
             instance.stop();
-            m_logger.log(Logger.ERROR, e.getMessage(), e);
+            m_logger.log(Logger.INFO, "An error occurred when creating an instance of " + getFactoryName(), e);
             throw new ConfigurationException(e.getMessage(), e);
         }
 

Added: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/AggregateDependencyInjectionType.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/AggregateDependencyInjectionType.java?rev=1527496&view=auto
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/AggregateDependencyInjectionType.java (added)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/AggregateDependencyInjectionType.java Mon Sep 30 09:34:36 2013
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.util.*;
+
+/**
+ * An enumeration listing the different possibility to inject an aggregate dependency in a field or constructor
+ * parameter.
+ */
+public enum AggregateDependencyInjectionType {
+
+    ARRAY,
+    LIST,
+    SET,
+    VECTOR;
+
+    public static List<String> AGGREGATE_TYPES =
+        Arrays.asList(
+                List.class.getName(),
+                Vector.class.getName(),
+                Set.class.getName(),
+                Collection.class.getName());
+}

Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=1527496&r1=1527495&r2=1527496&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Mon Sep 30 09:34:36 2013
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.felix.ipojo.handlers.dependency;
 
 import org.apache.felix.ipojo.*;
@@ -80,10 +81,11 @@ public class Dependency extends Dependen
      */
     private ServiceUsage m_usage;
     /**
-     * Type of the object to inject.
+     * Type of the object to inject in aggregate dependency. This value is used to determine what kind of object need
+     * to be injected for fields and constructor parameter for aggregate dependencies.
      * Cannot change once set.
      */
-    private int m_type;
+    private AggregateDependencyInjectionType m_type;
     /**
      * Nullable object.
      * Immutable once set.
@@ -107,6 +109,10 @@ public class Dependency extends Dependen
      * -1 if not used.
      */
     private int m_index = -1;
+
+    /**
+     * The dependency timeout.
+     */
     private int m_timeout;
 
     /**
@@ -599,6 +605,16 @@ public class Dependency extends Dependen
         }
     }
 
+
+    /**
+     * Gets the list of callbacks attached to the current dependency.
+     * @return the array of dependency callback, {@code null} if no callbacks are attached to the current dependency.
+     */
+    public DependencyCallback[] getDependencyCallbacks() {
+        return m_callbacks;
+    }
+
+
     /**
      * Called by the proxy to get  service objects to delegate a method.
      * On aggregate dependencies, it returns a list.
@@ -690,7 +706,7 @@ public class Dependency extends Dependen
     public Object onGet(Object pojo, String fieldName, Object value) {
 
         // Initialize the thread local object is not already touched.
-        Usage usage = (Usage) m_usage.get();
+        Usage usage = m_usage.get();
         if (usage.m_stack == 0) { // uninitialized usage.
             createServiceObject(usage);
             usage.inc(); // Start the caching, so set the stack level to 1
@@ -737,59 +753,60 @@ public class Dependency extends Dependen
                 usage.m_object = getService(ref);
             }
         } else {
-            if (m_type == 0) { // Array
-                try {
+            switch(m_type) {
+                case ARRAY:
+                    try {
+                        if (refs == null) {
+                            usage.m_object = (Object[]) Array.newInstance(getSpecification(), 0); // Create an empty array.
+                        } else {
+                            //  Use a reflective construction to avoid class cast exception. This method allows setting the component type.
+                            Object[] objs = (Object[]) Array.newInstance(getSpecification(), refs.length);
+                            for (int i = 0; i < refs.length; i++) {
+                                ServiceReference ref = refs[i];
+                                objs[i] = getService(ref);
+                            }
+                            usage.m_object = objs;
+                        }
+                    } catch (ArrayStoreException e) {
+                        throw new RuntimeException("Cannot create the array - Check that the bundle can access the service interface", e);
+                    }
+                    break;
+                case LIST:
                     if (refs == null) {
-                        usage.m_object = (Object[]) Array.newInstance(getSpecification(), 0); // Create an empty array.
+                        usage.m_object = Collections.emptyList();
                     } else {
-                        //  Use a reflective construction to avoid class cast exception. This method allows setting the component type.
-                        Object[] objs = (Object[]) Array.newInstance(getSpecification(), refs.length);
-                        for (int i = 0; i < refs.length; i++) {
-                            ServiceReference ref = refs[i];
-                            objs[i] = getService(ref);
+                        // Use a list to store service objects
+                        List<Object> objs = new ArrayList<Object>(refs.length);
+                        for (ServiceReference ref : refs) {
+                            objs.add(getService(ref));
                         }
                         usage.m_object = objs;
                     }
-                } catch (ArrayStoreException e) {
-                    m_handler.error("Cannot create the array - Check that the bundle can access the service interface", e);
-                    throw new RuntimeException("Cannot create the array - Check that the bundle can access the service interface", e);
-                }
-            } else if (m_type == DependencyHandler.LIST) {
-                if (refs == null) {
-                    usage.m_object = new ArrayList(0); // Create an empty list.
-                } else {
-                    // Use a list to store service objects
-                    List objs = new ArrayList(refs.length);
-                    for (int i = 0; refs != null && i < refs.length; i++) {
-                        ServiceReference ref = refs[i];
-                        objs.add(getService(ref));
-                    }
-                    usage.m_object = objs;
-                }
-            } else if (m_type == DependencyHandler.VECTOR) {
-                if (refs == null) {
-                    usage.m_object = new Vector(0); // Create an empty vector.
-                } else {
-                    // Use a vector to store service objects
-                    Vector objs = new Vector(refs.length);
-                    for (int i = 0; refs != null && i < refs.length; i++) {
-                        ServiceReference ref = refs[i];
-                        objs.add(getService(ref));
+                    break;
+                case SET:
+                    if (refs == null) {
+                        usage.m_object = Collections.emptySet();
+                    } else {
+                        // Use a vector to store service objects
+                        Set<Object> objs = new HashSet<Object>(refs.length);
+                        for (ServiceReference ref : refs) {
+                            objs.add(getService(ref));
+                        }
+                        usage.m_object = objs;
                     }
-                    usage.m_object = objs;
-                }
-            } else if (m_type == DependencyHandler.SET) {
-                if (refs == null) {
-                    usage.m_object = new HashSet(0); // Create an empty vector.
-                } else {
-                    // Use a vector to store service objects
-                    Set objs = new HashSet(refs.length);
-                    for (int i = 0; refs != null && i < refs.length; i++) {
-                        ServiceReference ref = refs[i];
-                        objs.add(getService(ref));
+                    break;
+                case VECTOR:
+                    if (refs == null) {
+                        usage.m_object = new Vector(0); // Create an empty vector.
+                    } else {
+                        // Use a vector to store service objects
+                        Vector<Object> objs = new Vector<Object>(refs.length);
+                        for (ServiceReference ref : refs) {
+                            objs.add(getService(ref));
+                        }
+                        usage.m_object = objs;
                     }
-                    usage.m_object = objs;
-                }
+                    break;
             }
         }
     }
@@ -841,7 +858,7 @@ public class Dependency extends Dependen
      */
     public void onEntry(Object pojo, Member method, Object[] args) {
         if (m_usage != null) {
-            Usage usage = (Usage) m_usage.get();
+            Usage usage = m_usage.get();
             usage.incComponentStack(); // Increment the number of component access.
             if (usage.m_stack > 0) {
                 usage.inc();
@@ -884,13 +901,14 @@ public class Dependency extends Dependen
      */
     public void onFinally(Object pojo, Member method) {
         if (m_usage != null) {
-            Usage usage = (Usage) m_usage.get();
+            Usage usage = m_usage.get();
             usage.decComponentStack();
             if (usage.m_stack > 0) {
                 if (usage.dec()) {
                     // Exit the method flow => Release all objects
                     usage.clear();
-                    m_usage.set(usage); // Set the Thread local as value has been modified
+                    // Also remove the thread local object.
+                    m_usage.remove();
                 }
             }
         }
@@ -902,7 +920,9 @@ public class Dependency extends Dependen
      * @return true if the dependency is optional and supports nullable objects.
      */
     public boolean supportsNullable() {
-        return m_supportNullable;
+        return isOptional()
+                && ! isAggregate()
+                && m_supportNullable;
     }
 
     public String getDefaultImplementation() {
@@ -921,9 +941,9 @@ public class Dependency extends Dependen
      * Set the type to inject.
      * This method set the dependency as aggregate.
      *
-     * @param type either list of vector
+     * @param type the type to inject.
      */
-    protected void setType(int type) {
+    protected void setAggregateType(AggregateDependencyInjectionType type) {
         setAggregate(true);
         m_type = type;
     }
@@ -974,11 +994,10 @@ public class Dependency extends Dependen
         if (m_index == index && m_proxyObject != null) {
             if (isAggregate()) {
                 switch (m_type) {
-                    case DependencyHandler.LIST:
+                    case LIST:
                         return List.class;
-                    case DependencyHandler.SET:
+                    case SET:
                         return Set.class;
-                    //TODO We should also manage the Collection type.
                     default:
                         return null; // Should never happen, it was checked before.
                 }
@@ -990,6 +1009,18 @@ public class Dependency extends Dependen
         }
     }
 
+    public String getException() {
+        return m_exception;
+    }
+
+    public int getTimeout() {
+        return m_timeout;
+    }
+
+    public AggregateDependencyInjectionType getAggregateType() {
+        return m_type;
+    }
+
     /**
      * Classloader for nullable objects.
      */
@@ -1173,7 +1204,7 @@ public class Dependency extends Dependen
             Class declaringClass = method.getDeclaringClass();
             if (declaringClass == Object.class) {
                 if (method.equals(m_hashCodeMethod)) {
-                    return new Integer(this.hashCode());
+                    return this.hashCode();
                 } else if (method.equals(m_equalsMethod)) {
                     return proxy == args[0] ? Boolean.TRUE : Boolean.FALSE;
                 } else if (method.equals(m_toStringMethod)) {

Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java?rev=1527496&r1=1527495&r2=1527496&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java Mon Sep 30 09:34:36 2013
@@ -1,4 +1,4 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -18,20 +18,17 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
 import org.apache.felix.ipojo.util.Callback;
 import org.osgi.framework.ServiceReference;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
+
 /**
  * This class allwos the creation of callback when service dependency arrives or
  * disappear.
- * 
+ *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class DependencyCallback extends Callback {
@@ -40,44 +37,38 @@ public class DependencyCallback extends 
      * Bind method (called when a service arrives).
      */
     public static final int BIND = 0;
-
     /**
      * Unbind method (called when a service disappears).
      */
     public static final int UNBIND = 1;
-    
     /**
      * Updated method (called when a service is modified).
      */
     public static final int MODIFIED = 2;
-
     /**
      * Is the method a bind method or an unbind method ?
      */
     private int m_methodType;
-    
     /**
      * Arguments of the callback.
      */
     private String[] m_argument;
-
     /**
      * Callback method name.
      */
     private String m_method;
-    
     /**
-     * Service Dependency. 
+     * Service Dependency.
      */
     private Dependency m_dependency;
 
     /**
      * Constructor.
-     * 
-     * @param dep : the dependency attached to this dependency callback
-     * @param method : the method to call
+     *
+     * @param dep        : the dependency attached to this dependency callback
+     * @param method     : the method to call
      * @param methodType : is the method to call a bind method or an unbind
-     * method
+     *                   method
      */
     public DependencyCallback(Dependency dep, String method, int methodType) {
         super(method, (String[]) null, false, dep.getHandler().getInstanceManager());
@@ -86,23 +77,23 @@ public class DependencyCallback extends 
         m_method = method;
     }
 
-
     public int getMethodType() {
         return m_methodType;
     }
-    
+
     public String getMethodName() {
         return m_method;
     }
-    
+
     /**
      * Set the argument type (Empty or the class name).
+     *
      * @param arg : the array of argument types.
      */
     public void setArgument(String[] arg) {
         m_argument = arg;
     }
-    
+
     /**
      * Search the method object in the POJO by analyzing present method.
      * If not found in the pojo it tests the parent classes.
@@ -111,11 +102,11 @@ public class DependencyCallback extends 
     protected void searchMethod() {
         if (m_argument != null) {
             Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getDeclaredMethods();
-            for (int i = 0; i < methods.length; i++) {
+            for (Method method : methods) {
                 // First check the method name
-                if (methods[i].getName().equals(m_method)) {
+                if (method.getName().equals(m_method)) {
                     // Check arguments
-                    Class[] clazzes = methods[i].getParameterTypes();
+                    Class[] clazzes = method.getParameterTypes();
                     if (clazzes.length == m_argument.length) { // Test size to avoid useless loop // NOPMD
                         int argIndex = 0;
                         for (; argIndex < m_argument.length; argIndex++) {
@@ -124,8 +115,8 @@ public class DependencyCallback extends 
                             }
                         }
                         if (argIndex == m_argument.length) { // If the array was completely read.
-                            m_methodObj = methods[i]; // It is the looked method.
-                            if (! m_methodObj.isAccessible()) { 
+                            m_methodObj = method; // It is the looked method.
+                            if (!m_methodObj.isAccessible()) {
                                 // If not accessible, try to set the accessibility.
                                 m_methodObj.setAccessible(true);
                             }
@@ -136,22 +127,24 @@ public class DependencyCallback extends 
                 }
             }
         }
-        
+
         // Not found => Try parent method.
         searchParentMethod();
-        
+
         if (m_methodObj == null) {
             // If not found, stop the instance (fatal error)
-            m_dependency.getHandler().error("The method " + m_method + " cannot be called : method not found");
+            m_dependency.getHandler().error("The dependency callback method " + m_method + " cannot be invoked - " +
+                    "reason: the method is not defined in the component class (" + m_dependency.getHandler()
+                    .getInstanceManager().getClazz().getName() + ")");
             m_dependency.getHandler().getInstanceManager().stop();
         } else {
-            if (! m_methodObj.isAccessible()) { 
+            if (!m_methodObj.isAccessible()) {
                 // If not accessible, try to set the accessibility.
                 m_methodObj.setAccessible(true);
             }
         }
     }
-    
+
     /**
      * Introspect parent class to find the method.
      */
@@ -174,14 +167,14 @@ public class DependencyCallback extends 
                         if (clazzes[0].getName().equals(ServiceReference.class.getName())) {
                             // Callback with a service reference.
                             m_methodObj = methods[i];
-                            m_argument = new String[] { ServiceReference.class.getName() };
+                            m_argument = new String[]{ServiceReference.class.getName()};
                             return;
                         }
                         // The callback receives a Service object
                         if (clazzes[0].getName().equals(m_dependency.getSpecification().getName())) {
                             // Callback with the service object.
                             m_methodObj = methods[i];
-                            m_argument = new String[] { m_dependency.getSpecification().getName() };
+                            m_argument = new String[]{m_dependency.getSpecification().getName()};
                             return;
                         }
                         break;
@@ -190,21 +183,21 @@ public class DependencyCallback extends 
                         if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(ServiceReference.class.getName())) {
                             // Callback with two arguments.
                             m_methodObj = methods[i];
-                            m_argument = new String[] { m_dependency.getSpecification().getName(), ServiceReference.class.getName() };
+                            m_argument = new String[]{m_dependency.getSpecification().getName(), ServiceReference.class.getName()};
                             return;
                         }
                         // The callback receives the service object and the service properties (in a Map)
                         if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(Map.class.getName())) {
                             // Callback with two arguments.
                             m_methodObj = methods[i];
-                            m_argument = new String[] { m_dependency.getSpecification().getName(), Map.class.getName() };
+                            m_argument = new String[]{m_dependency.getSpecification().getName(), Map.class.getName()};
                             return;
                         }
                         // The callback receives the service object and the service properties (in a Dictionary)
                         if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(Dictionary.class.getName())) {
                             // Callback with two arguments.
                             m_methodObj = methods[i];
-                            m_argument = new String[] { m_dependency.getSpecification().getName(), Dictionary.class.getName() };
+                            m_argument = new String[]{m_dependency.getSpecification().getName(), Dictionary.class.getName()};
                             return;
                         }
                         break;
@@ -217,38 +210,38 @@ public class DependencyCallback extends 
 
     /**
      * Call the callback method with a service reference.
-     * 
+     *
      * @param ref : the service reference to send to the method
      * @param obj : the service object
-     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws NoSuchMethodException     : Method is not found in the class
      * @throws InvocationTargetException : The method is not static
-     * @throws IllegalAccessException : The method can not be invoked
+     * @throws IllegalAccessException    : The method can not be invoked
      */
     protected void call(ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         if (m_methodObj == null) {
             searchMethod();
         }
         switch (m_argument.length) {
-            case 0 :
+            case 0:
                 call(new Object[0]);
                 break;
-            case 1 : 
+            case 1:
                 if (m_argument[0].equals(ServiceReference.class.getName())) {
-                    call(new Object[] {ref});
+                    call(new Object[]{ref});
                 } else {
-                    call(new Object[] {obj});
+                    call(new Object[]{obj});
                 }
                 break;
-            case 2 :
+            case 2:
                 if (m_argument[1].equals(ServiceReference.class.getName())) {
-                    call(new Object[] {obj, ref});
+                    call(new Object[]{obj, ref});
                 } else if (m_argument[1].equals(Dictionary.class.getName())) {
-                    call(new Object[] {obj, getPropertiesInDictionary(ref)});
+                    call(new Object[]{obj, getPropertiesInDictionary(ref)});
                 } else {
-                    call(new Object[] {obj, getPropertiesInMap(ref)});
+                    call(new Object[]{obj, getPropertiesInMap(ref)});
                 }
                 break;
-            default : 
+            default:
                 break;
         }
     }
@@ -256,6 +249,7 @@ public class DependencyCallback extends 
     /**
      * Creates a {@link Dictionary} containing service properties of the
      * given service reference.
+     *
      * @param ref the service reference
      * @return a {@link Dictionary} containing the service properties.
      */
@@ -267,10 +261,11 @@ public class DependencyCallback extends 
         }
         return dict;
     }
-    
+
     /**
      * Creates a {@link Map} containing service properties of the
      * given service reference.
+     *
      * @param ref the service reference
      * @return a {@link Map} containing the service properties.
      */
@@ -283,15 +278,14 @@ public class DependencyCallback extends 
         return map;
     }
 
-
     /**
      * Call the callback on the given instance with the given argument.
-     * 
+     *
      * @param instance : the instance on which call the callback
-     * @param ref : the service reference to send to the callback
-     * @param obj : the service object
-     * @throws NoSuchMethodException : the method is not found
-     * @throws IllegalAccessException : the method could not be called
+     * @param ref      : the service reference to send to the callback
+     * @param obj      : the service object
+     * @throws NoSuchMethodException     : the method is not found
+     * @throws IllegalAccessException    : the method could not be called
      * @throws InvocationTargetException : an error happens in the called method
      */
     protected void callOnInstance(Object instance, ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
@@ -299,26 +293,26 @@ public class DependencyCallback extends 
             searchMethod();
         }
         switch (m_argument.length) {
-            case 0 :
+            case 0:
                 call(instance, new Object[0]);
                 break;
-            case 1 : 
+            case 1:
                 if (m_argument[0].equals(ServiceReference.class.getName())) {
-                    call(instance, new Object[] {ref});
+                    call(instance, new Object[]{ref});
                 } else {
-                    call(instance, new Object[] {obj});
+                    call(instance, new Object[]{obj});
                 }
                 break;
-            case 2 :
+            case 2:
                 if (m_argument[1].equals(ServiceReference.class.getName())) {
-                    call(instance, new Object[] {obj, ref});
+                    call(instance, new Object[]{obj, ref});
                 } else if (m_argument[1].equals(Dictionary.class.getName())) {
-                    call(instance, new Object[] {obj, getPropertiesInDictionary(ref)});
+                    call(instance, new Object[]{obj, getPropertiesInDictionary(ref)});
                 } else {
-                    call(instance, new Object[] {obj, getPropertiesInMap(ref)});
+                    call(instance, new Object[]{obj, getPropertiesInMap(ref)});
                 }
                 break;
-            default : 
+            default:
                 break;
         }
     }