Hi Bruce,

The behaviour you described is correct from a DS point of view. Dynamic 
references can be bound at any time, from any thread before, during or after 
activation. They can even be bound/unbound multiple times during activation. 
Therefore you cannot rely on a dynamic reference from your activate method or 
vice versa.

Even if you make this a static reference, those are required to invoke before 
activate, therefore your code will be guaranteed to throw NPE (whereas your 
current code only *probably* NPEs).

There are a couple of options. Does your ‘processor’ object actually depend on 
anything that is initialised in component activation? I.e., does it need access 
to ComponentContent or BundleContext, or the component config? If not then you 
can just make it a final field and initialise it during construction.

If it does then you have to defer the invocation of processor.process(). I 
suggest you use a final List of Foo objects (or ServiceReference<Foo>). The 
bindFoo method detects whether the processor exists yet, and if not it just 
adds the Foo onto the list. That list should be drained by the activate method 
after it initialises the processor. Note you will have to write this with 
thread safety because, as I said, the activate and bind/unbindFoo methods can 
be called from separate threads.

Obviously this is a little complex so it’s far better if you can just 
initialise processor in your constructor.

Neil

> On 12 May 2017, at 08:05, Bruce Jackson <bruce.jack...@myriadgroup.com> wrote:
> 
> Hi Everyone
> 
> I was wondering if anyone could provide some advice:
> 
> I have a component of the form:
> 
> @Component(name="Bar")
> public class MyComponent {
> 
> private MyServiceProcessor processor;
> 
> @Activate
> public void activate(ComponentContext cc) {
> 
> processor = new MyServiceProcessor();
> 
> }
> 
> @Deactivate
> public void deactivate(ComponentContext cc) {
> 
> }
> 
> @Reference(cardinality = ReferenceCardinality.MULTIPLE)
> public void bindFoo(ServiceReference<Foo> ref) {
> 
> /* some code here */
> processor.process(ref.getService());
> /* some more code here */
> 
> }
> 
> public void unbindFoo(ServiceReference<Foo> ref) {
> 
> }
> 
> }
> 
> The problem here is that the bindFoo() method is called by the SCR before the 
> activate and thus a null pointer exception is thrown in the 
> processor.process() call.
> This is perhaps not surprising, but it is not ideal for a component that is 
> ‘lazy’ about the other services that it wants to discover. I could clearly 
> move this functionality into a ServiceTracker which I create in the 
> activate() but was wondering if there was another approach that allowed me to 
> do this via DS and annotations?
> 
> Best regards
> 
> Bruce
> 
> 
> *** DISCLAIMER *** This message, including attachments, is intended solely 
> for the addressee indicated in this message and is strictly confidential or 
> otherwise privileged. If you are not the intended recipient (or responsible 
> for delivery of the message to such person) : - (1) please immediately (i) 
> notify the sender by reply email and (ii) delete this message and 
> attachments, - (2) any use, copy or dissemination of this transmission is 
> strictly prohibited. If you or your employer does not consent to Internet 
> email messages of this kind, please advise Myriad Group AG by reply e-mail 
> immediately. Opinions, conclusions and other information expressed in this 
> message are not given or endorsed by Myriad Group AG unless otherwise 
> indicated by an authorized representative independent of this message.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
> For additional commands, e-mail: users-h...@felix.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org

Reply via email to