Using declared osgi services inside an RCP application [message #547480] |
Sat, 17 July 2010 09:45  |
Eclipse User |
|
|
|
Hi,
I'm developing my own RCP application with 3 plugins. One is the "model" and has an IModel interface, another is my "service" plugin in which a class ModelImpl implements the IModel interface and declares a service inside a component.xml file. The last one is a "ui" plugin that defines my RCP product and uses the declared service (also using a component.xml file).
When I debug the application using the RCP debugger the service binding method Activator.setModel of the ui plugin never gets called, but it gets called when I run the same plugin inside the OSGI framework debugger. Do I need to set something special on the RCP debugger or any of my plugins?
FYI the model and service plugins don't have an Activator class. Thanks for you help.
Regards,
|
|
|
|
|
Re: Using declared osgi services inside an RCP application [message #547615 is a reply to message #547577] |
Mon, 19 July 2010 03:23   |
Eclipse User |
|
|
|
On 19.07.2010 03:31, elgabo81@gmail.com wrote:
> Hi Tom,
>
> I think that the osgi runtime must call it automagically, because there
> is plugin that defines a service (service plugin) and another one that
> consumes it (ui plugin).
You did not explain in any word that your Activator class is also
supposed to be an osgi component. Your new description implies this
somehow, but that was not clear from begin with.
> But I think I found something interesting. The Activator.setModel method
> is being called, but not for the correct instance.
It's not clear what you mean with this. Note that an osgi bundle
activator and an osgi component are conceptually different things.
It is true, that some aspects allow to compare the specification
of an bundle activator to behave *similar* to a component, but
the osgi spec does not say that an bundle activator *is* an osgi
component. So you cannot impose requirements on a type that you
use for *both* an activator and a component. In fact, I would
strongly recommend to *never* mix these responsibilities.
> The "Component Resolve Thread" is instancing the ui plugin Activator
class twice:
>
> 1) AbstractBundle.loadBundleActivator() line 151
> 2) ServiceComponent.createInstance line 457
>
> The method start(BundleContext) of the first instance is gets called and
> the method setModel(IModel) of the second instance gets called. So the
> model is not being setted correctilly on the singleton instance. Is
> there a plugin.xml or component.xml configuration that prevents this
> from happening?
>
> I worked around this issue using this code:
>
>
> public void setModelo(IModelo model) {
> Activator.getDefault().model=model;
> }
>
> public void unsetModelo(IModel model) {
> Activator.getDefault().model=null;
> }
>
I would separate concerns. Don't make the bundle activator an osgi
component. Just define a separate osgi component and if user-code
should be able to access the model via the activator as well, it is
easy to solve this as you describe above:
public void setModelo(IModelo model) {
Activator.getDefault().setModel(model);
}
public void unsetModelo(IModel model) {
Activator.getDefault().setModel(null);
}
HTH & Greetings from Bremen,
Daniel Krügler
|
|
|
|
Re: Using declared osgi services inside an RCP application [message #548208 is a reply to message #548191] |
Wed, 21 July 2010 01:56  |
Eclipse User |
|
|
|
On 21.07.2010 04:58, Gabriel wrote:
> I'll try to explain myself a little
> better, from my point of view it's really important that the service
> implementation can be accessed easily from any class of my ui plugin and
> to always get that same reference. That is why I think a reference to
> the service on the Activator is needed, because Activator is a
> singleton.
Fair enough. But let me just remark, that such an "access point" is not
strictly necessary, because a properly configured service component
will also be a singleton and user code would just need to query the
osgi service registry to get access to it. Nonetheless your use-case
is understandable and makes sense.
> This way I can define and call
> Activator.getDefault().getModel(). I separated the concerns as you
> recommended by creating this class:
>
>
> public class ModelConsumer {
> public void setModel(IModel model) {
> Activator.getDefault().setModel(modelo);
> }
>
> public void unsetModel(IModel model) {
> Activator.getDefault().setModel(null);
> }
> }
>
>
> Please do tell me if this has some potential issues or if there is a
> "best practice" approach. Thanks for your help.
I think that this is exactly the route to go. You should
ensure that your bundle manifest uses the bundle activation
policy lazy, but that's all.
The effect will be, that at the point of construction of
your ModelConsumer service component the Activator has also
been started.
HTH & Greetings from Bremen,
Daniel Krügler
|
|
|
Powered by
FUDForum. Page generated in 0.07782 seconds