0

I have 3 component (A,B,C) providing services (As,As,Cs) (A and B implement the same (As) service). and 1 component (E) requiring service.

The component class of E, i declared:

@Component 
@.....
class E {
    @requires
    As dep1,
}

I have a controller to set a filter of "dep1". It controls "dep1" choosing the (As) service of components, A or B.

All components work fine. and i can control As service between A and B component.

Now, I modify the class E following:

@Component 
@.....
class E {
    @requires
    As dep1;
    @requires 
    Cs dep2;
}

In this case, i can also control the filter from a controller but :

"dep1" uses always service of component "A", in spite of the filter of "dep1" sets to "B"

How to resolve this case, please? Thanks in advance.

HNT
  • 147
  • 1
  • 10
  • What do you mean by "controller". What does the 'instance' command gives you after the reconfiguration ? – Clement Nov 14 '14 at 06:17
  • Controller is a component which controls filter setting of dependency. I resolved this issus with command: dependency.resetLocalCache(); However, i don't understand why. Could you help me explain this command ? Thanks, – HNT Nov 14 '14 at 08:42
  • You should not use 'resetLocalCache', what's happening is that you don't follow the synchronization protocol implemented by iPOJO. A component will use the SAME services until the end of the method, even if new services are arriving, or one of the used one is leaving (it will be released once the method exits). Check http://www.osgi.org/wiki/uploads/CommunityEvent2008/25_%20Hall_ipojo-berlin-20080611.pdf for details. – Clement Nov 16 '14 at 10:50
  • Clement, i don't think that relates the synchronization protocol. I used "synchronized" before the methods using. Moreover, all methods in this case are the end. – HNT Nov 21 '14 at 16:02

1 Answers1

0

I don’t know why it does not work fine if I don’t use resetLocalCache in controller component. This is my program

  1. A Component uses services

@Component(name="callHello", immediate=true)

@Instantiate
public class CallHello {

    @Requires(filter="(name.instance=A)")
    DelayService delayService;
    @Requires
    DirectService directService;
    public CallHello() {
    ...
        Label lb = new Label();
        Button bt = new Button("Printer 1");
        pn.add(bt);
        bt.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (directService != null)
            lb.setText(delayService.informDelay(tf.getText()));
                    }
        });
       ...
    }
    }
  1. Controller component

    @Component(name="Controller", immediate=true)

    @Instantiate

    public class ReconfigurationController {

     ...
    public ReconfigurationController() {
    
        fr = new JFrame("Controller");
        fr.setSize(350,150);
        ...
        final Button bt2 = new Button("To 2");
        bt2.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (chk2) {
                if (changeConnector(ctx, "hello.call.CallHello", "hello", "delayService", "B")) {
                    bt2.setLabel("To 1");
                    chk2 = false;
                }
            } else { 
                if (changeConnector(ctx, "hello.call.CallHello", "hello", "delayService", "A")) {
                    bt2.setLabel("To 2");
                    chk2 = true;
                }
            }
        }});
    ...
    public boolean changeConnector(BundleContext ctx, String componentName, String srcInstanceName, String dependencyName, String dstInstanceName) {
        boolean result = false;
        ServiceReference[] references;
        try {
            references = ctx.getServiceReferences(Factory.class.getName()," (factory.name="+componentName+")"); 
            Factory fact = (Factory)ctx.getService(references[0]);
    
            InstanceManager im = (InstanceManager) fact.getInstances().get(0);
            for(ComponentInstance ci: fact.getInstances()) {
            //System.out.println(ci.getInstanceName());
            if (ci.getInstanceName().equals(srcInstanceName) ) {
                im = (InstanceManager)ci;
            }
        }
        DependencyHandler handler = (DependencyHandler) im.getHandler("org.apache.felix.ipojo:requires");
        Dependency[] deps = handler.getDependencies();
        for (Dependency d : deps ) {
            // Lookup your dependency from deps (by id, by specification…)
            if (d.getField().equals(dependencyName)) {
                String srcFilter = d.getFilter();
                Filter filter = FrameworkUtil.createFilter("(instance.name="+dstInstanceName+")");
                d.setFilter(filter);
    
                if (d.getState() == 1) {
                    result = true;
                    d.resetLocalCache();
                } else {
                    System.out.println("rollback");
                    filter = FrameworkUtil.createFilter(srcFilter);
                    //d.setFilter(filter);
                    result = false;
                }
            }
        }
    } catch (InvalidSyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return result;
    }
    

    }

  2. I have 2 component instances (A and B)which provide service “informDelay”

HNT
  • 147
  • 1
  • 10