Hi Todor,

thank you so much for your detailed explanation and the additional links.
That helped me a lot to simplify my implementation for Vaadin.

Hopefully this will lead to a seamless integration between Vaadin and OSGi.

Kind regards,
Thomas

Am Di., 12. Feb. 2019 um 11:05 Uhr schrieb Boev, Todor <
todor.b...@softwareag.com>:

> Hi Thomas,
>
> A better design would be to implement a whiteboard pattern rather than an
> extender.
> Rather than to track and scan bundles it is better to track OSGi services
> that extend Component and
> plug those into Vaadin directly.
>
> To make sure Vaadin gets a fresh object every time it needs you can
> recommend to your users to
> register their services with a property "service.scope=prototype". This
> property instructs the OSGi
> framework to create a new object every time an attempt is made to grab the
> service. Your
> OSGiInstantiator will then just grab the service every time it is asked to
> create an object.
> The users may still choose to use a singleton object if it is stateless
> for example.
>
> In this design you abstract away how the users choose to create and
> register their service.
> In the case when they choose Declarative Services they will create a
> regular DS component
> with "service.scope=prototype". No need of a component factory.
>
> The OSGiInstantiator has to hold on to objects of this type:
>
> https://osgi.org/javadoc/osgi.core/7.0.0/org/osgi/framework/ServiceObjects.html
> Which are obtained like this:
>
>
> https://osgi.org/javadoc/osgi.core/7.0.0/org/osgi/framework/BundleContext.html#getServiceObjects-org.osgi.framework.ServiceReference
> -
> It has to store the service instances it creates and release them when
> appropriate.
>
> The principles of this design are tried and tested in OSGi specifications
> like the
> Http integration - where the core gathers Servlet and Filter services or
> the JAX-RS integration
> where the core gathers resources.
>
> In my opinion the major technical issues you face are:
> 1. You likely have to pass to Vaadin all classes that it needs to plug
> into the web app ahead of
> time. This means you need to inspect each Component service when it
> arrives to get it's concrete
> class. Basically probe the service by getting one instance then getting
> it's class then releasing
> the instance. Then you may need to reboot the Vaadin application with the
> new class added.
>
> 2. The OSGiInstantiator is created through ServiceLoader. This means you
> can not initialize it with
> the concrete OSGi service object. It may have to pass through static
> fields that are populated with
> the Component services by other parts of your whiteboard. This can also
> introduce lifecycle issues
> since the OSGiIntantiator may be created before a service it needs is
> added so it may need to block
> for a period of time. If you can pass a ready made OSGiInstantiator to
> Vaadin it will be ideal.
>
> These implementation complications are well worth the power/simplicity you
> give the users to
> completely control the lifecycle and implementation style of their
> components.
>
>
> P.S. With all that said I think there is a real issue with DS and
> programmatic creation of
> components. Since component factories are frowned upon the next best thing
> is to register
> "service.scope=prototype" services that may need setters or initializtion
> methods. The party
> that needs to make programmatically the component can grab a fresh
> instance and the customize it.
> Another pattern I have used is to just add configurations to ConfigAdmin.
>
> Hope this helps,
> Todor
>
>
> On Mon, 2019-02-11 at 09:12 +0000, Thomas Driessen via osgi-dev wrote:
> > Hi Ray,
> >
> > thanks for your time and advice.
> >
> > Regarding your question:
> >
> > The classes are annotated by whoever wants to register a @Route in
> Vaadin. Routes in Vaadin are
> > usually a specific location within a web application. Classes that are
> annotated with @Route are
> > extending Vaadin's Component class and are instantiated by Vaadin
> whenever a new client requests
> > the respective part of the web application. Vaadin delegates the
> instantiation of the class to an
> > Instantiator,  this is usually the DefaultInstantiator class in Vaadin.
> >
> > I try to delegate this instantiation to OSGi by extending Vaadins
> DefaultInstantiator and
> > registering the new OSGiInstantiator via ServiceLoader mechanism which
> is internally used by
> > Vaadin to find its Instantiators.
> > Whenever Vaadin calls an Instantiator it passes a class that has to be
> instantiated.
> > This is the place where I'm using ComponentFactory to create instances
> of those classes.
> >
> > You can also have a look on all of these classes and additional
> information about the intended
> > logic flow at my repository:
> > https://github.com/Sandared/flow-osgi
> >
> > Kind regards,
> > Thomas
> >
> >
> > ------ Originalnachricht ------
> > Von: "Raymond Auge" <raymond.a...@liferay.com>
> > An: "Thomas Driessen" <thomas.driessen...@gmail.com>
> > Cc: "OSGi Developer Mail List" <osgi-dev@mail.osgi.org>
> > Gesendet: 10.02.2019 18:05:56
> > Betreff: Re: [osgi-dev] Programmatically creating DS components
> >
> > >
> > > On Sun, Feb 10, 2019 at 11:20 AM Thomas Driessen <
> thomas.driessen...@gmail.com> wrote:
> > > > Hi Ray,
> > > >
> > > > I'm not defining any additional manifest header if that's what you
> mean. I have no real
> > > > control over the bundles I need to scan.
> > > >
> > > > What I do is registering a BundleTracker that scans a bundle's
> classes if its wiring states it
> > > > is importing the package of the annotation I'm looking for.
> > > > (Can be seen here:
> > > >
> https://github.com/Sandared/flow-osgi/blob/master/flow.osgi.integration/src/main/java/io/jatoms/flow/osgi/integration/FlowOsgiRouteTracker.java
> > > > )
> > > >
> > >
> > > This is precisely the "extender pattern" [1].
> > >
> > > > Those classes usually look something like this:
> > > >
> > > > @Route("")
> > > > @Component(factory="fqcn")
> > > > public class MyFancyUI extends Component {
> > > >   @Reference
> > > >    SomeService service;
> > > >   ...
> > > > }
> > > >
> > > > So I'm looking into the wiring of the bundle if it has imported the
> package
> > > > "com.vaadin.flow.router" . If so I then scan the bundle's classes
> for the @Route annotation
> > > > (and @RouteAlias).
> > > > Classes that have this annotation can later on be instantiated via
> ComponentFactory.
> > > >
> > > > Can I instantiate such a component with the Apache Aries approach
> and if so will its reference
> > > > be injected? I'm not sure if this is done if I'm registering the
> instance just as a service.
> > > >
> > >
> > > Let's start with how the classes came to be annotated with @Component,
> and why that isn't
> > > already enough.
> > >
> > > - Ray
> > >
> > > [1] https://blog.osgi.org/2007/02/osgi-extender-model.html
> > >
> > > > Kind regards,
> > > > Thomas
> > > >
> > > > Am So., 10. Feb. 2019 um 15:38 Uhr schrieb Raymond Auge <
> raymond.a...@liferay.com>:
> > > > > Are you implementing this using the extender pattern? If so, I
> would not use DS. I would use
> > > > > something lower level.
> > > > >
> > > > > There are plenty of good alternatives for doing this, but I would
> suggest looking at Apache
> > > > > Aries Component DSL [1] (it's what is used to implement Aries
> JAXRS Whiteboard).
> > > > >
> > > > > - Ray
> > > > >
> > > > > [1] https://github.com/apache/aries/tree/trunk/component-dsl
> > > > >
> > > > > On Sun, Feb 10, 2019 at 8:01 AM Thomas Driessen via osgi-dev <
> osgi-dev@mail.osgi.org> wrote:
> > > > > > Hi,
> > > > > >
> > > > > > I'm currently trying to sketch out a possible better OSGi
> integration for Vaadin 10+.
> > > > > >
> > > > > > For this I need to programmatically create DS components in
> order to make @
> > > > > > Route/@RouteAlias annotated classes also DS components.
> > > > > >
> > > > > > Right now I'm doing this via ComponentFactory and the assumption
> that all @Route annotated
> > > > > > classes are also annotated with
> > > > > > @Component(factory="fully qualified class name")
> > > > > >
> > > > > > I don't think this is the best way to do this. Having to type
> the fqcn seems rather
> > > > > > errorprone to me and therefore I wanted to ask if there is a
> better way (maybe even a
> > > > > > typesafe way) to do this?
> > > > > >
> > > > > > The code instantiating a component can be seen here:
> > > > > >
> https://github.com/Sandared/flow-osgi/blob/master/flow.osgi.integration/src/main/java/io/jatoms/flow/osgi/integration/FlowOsgiInstantiator.java
> > > > > > The class that shall be instantiated can be seen here:
> > > > > >
> https://github.com/Sandared/flow-osgi/blob/master/flow.osgi.simpleui/src/main/java/io/jatoms/flow/osgi/simpleui/MainView.java
> > > > > >
> > > > > > Any advice is highly appreciated.
> > > > > >
> > > > > > Kind regards,
> > > > > > Thomas
> > > > > > _______________________________________________
> > > > > > OSGi Developer Mail List
> > > > > > osgi-dev@mail.osgi.org
> > > > > > https://mail.osgi.org/mailman/listinfo/osgi-dev
> > > > >
> > > > >
> > > > > --
> > > > > Raymond Augé (@rotty3000)
> > > > > Senior Software Architect Liferay, Inc. (@Liferay)
> > > > > Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)
> > >
> > >
> > > _______________________________________________
> > > OSGi Developer Mail List
> > > osgi-dev@mail.osgi.org
> > > https://mail.osgi.org/mailman/listinfo/osgi-dev
>
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to