mathieuancelin / weld-osgi

This project aims to provide an OSGi integration for Weld. This project is no longer updated, see https://github.com/weld/core for updates
https://github.com/weld/core
12 stars 10 forks source link

Publishing a service that got injected another service from the same bundle might fail #65

Closed arcane86 closed 13 years ago

arcane86 commented 13 years ago

A class A annotated @Publish and a class B annotated @Publish within the same bundle. If B got A injected as a OSGi service, depending on ServicePublisher scan order, it might throw a NPE in DynamicServiceHandler (service tracker fail to find A).

@Publish
public class A {
}

@Publish
public class B {
    @Inject @OSGiService
    A a;
}

Fail if B is published before A.

mathieuancelin commented 13 years ago

Erf, we'll have to make it lazy

arcane86 commented 13 years ago

Here the problem: 1)CDI-OSGi has registered all the OSGiBean from @OSGiService injection point (and regular managed bean) 2)It is scanning class B 3)It tries to obtain an instance of B in order to register it as an OSGi service 4)Weld tries to instantiate managed bean for B 5)Weld tries tries to inject @OSGiService A 6)Weld tries to instantiate OSGiBean A 7)OSGiBean creates a proxy and an handler for class A

8)And tadaa OSGiBean tries to put both proxy and handler in a hashmap 9)Handler is called for the HashCode method 10)Handler tries to get the A OSGi service from the tracker (in order to call hashcode method) 11)Everyone gets the NPE :)

I'm looking for a workaround, using another thing that a HashMap.

mathieuancelin commented 13 years ago

Ok I see what's the problem and why it happened. Not sure you can use something else.

arcane86 commented 13 years ago

I got thing to work by intercepting the HashCode method in the DynamicServiceHandler and returning a HashCode without actually calling the method on the instance.

Now the problem is when the HashCode method is called by the user on the service. The returned result is mine, not the actual HashCode method of the service.

I'm looking for a way to know if the HashCode call comes from framework or user :)

mathieuancelin commented 13 years ago

Why do we put the proxy as a key ? And why do we put it in a map at all ?

Le 26 juil. 2011 à 09:51, arcane86 reply@reply.github.com a écrit :

Here the problem: 1)CDI-OSGi has registered all the OSGiBean from @OSGiService injection point (and regular managed bean) 2)It is scanning class B 3)It tries to obtain an instance of B in order to register it as an OSGi service 4)Weld tries to instantiate managed bean for B 5)Weld tries tries to inject @OSGiService A 6)Weld tries to instantiate OSGiBean A 7)OSGiBean creates a proxy and an handler for class A

8)And tadaa OSGiBean tries to put both proxy and handler in a hashmap 9)Handler is called for the HashCode method 10)Handler tries to get the A OSGi service from the tracker (in order to call hashcode method) 11)Everyone gets the NPE :)

I'm looking for a workaround, using another thing that a HashMap.

Reply to this email directly or view it on GitHub: https://github.com/mathieuancelin/weld-osgi/issues/65#issuecomment-1652375

arcane86 commented 13 years ago

We store the association Proxy/Handler in order to cleanly close handler (actually close the service tracker in the handler) when the instance (so the proxy) is destroyed.

I think i have a functional solution, just need to test it. (it involves putting a boolean in the handler to know if it is registered with the framework, if not the hashCode call is intercepted, otherwise no interception).

mathieuancelin commented 13 years ago

Sorry, comment lag ... I found the why. Maybe a better solution is to wrap the proxy in a special object.