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