Another alternative designed specifically for this scenario is the OSGi Service Loader Mediator Specification [1].
Java's default _service_ mechanism is Service Loader SPI. The Service Loader Mediator Specification adds a veneer of pure metadata over this to allow it to function in OSGi. There are even SPI annotations [2] in the Bnd project to help with this (you should be able to use these with the maven-bundle-plugin if necessary). In this way the code is exactly 100% identical in OSGi and outside it. Sincerely, - Ray [1] https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.loader.html [2] https://bnd.bndtools.org/chapters/240-spi-annotations.html On Thu, May 21, 2020 at 3:54 AM Neil Bartlett via osgi-dev < osgi-dev@mail.osgi.org> wrote: > Along the lines of Bernd's answer, here is what I do: > > 1. Use declarative services. > 2. For injection of service references, prefer constructor injection. > 3. The component implementation should be in a private package. However, > non-OSGi consumers don't know anything about exported versus private > packages, so they just directly instantiate the DS component instance. > Because we used constructor injection, it's clear what dependencies > they need to provide to the component. > 5. If there is a need to interact with OSGi's APIs (e.g. BundleContext), > keep that code in a separate factory component. Put this code in a separate > class from the "business logic". Don't necessarily worry about using a > separate package for this... because Java ClassLoading is extremely lazy, > non-OSGi consumers will only be exposed to the OSGi-specific code if they > go out of their way to load it. > > On Thu, 21 May 2020 at 01:50, Bernd Eckenfels via osgi-dev < > osgi-dev@mail.osgi.org> wrote: > >> Hello, >> >> We typically use declarative services (DS) with the Maven bundle plugin >> and Annotations. This leaves no (optional) OSGi framework dependency and >> still allows a compliant container to manage the lifecycle of the component. >> >> In some (rare) cases when you have to deal with service references or >> OSGi context and you need the core API it does also not hurt to make it >> optional, as long as the class which uses it (and would not resolve) is not >> used by the stand alone code. This is typically the case for OSGi first >> components which are made compatible with stand alone unit tests. >> >> You can even have the factory receive the service, and therefore be >> useable inside the runtime. >> >> An alternative is, to just have the bundle headers and no service, this >> is still useful to OSGi code in many instances where you don't have a >> service lifecycle. >> >> Gruss >> Bernd >> -- >> http://bernd.eckenfels.net >> ------------------------------ >> *Von:* osgi-dev-boun...@mail.osgi.org <osgi-dev-boun...@mail.osgi.org> >> im Auftrag von David Leangen via osgi-dev <osgi-dev@mail.osgi.org> >> *Gesendet:* Thursday, May 21, 2020 12:44:04 AM >> *An:* osgi-dev@mail.osgi.org <osgi-dev@mail.osgi.org> >> *Betreff:* [osgi-dev] Library development >> >> Hi! >> >> What is the best way to prepare a library to OSGi-compatible, but not >> force the use of OSGi (including forcing transitive dependencies)? >> >> The library should be split into api / implementation and offered as a >> service, but it should be possible for those who do not use OSGi to obtain >> the implementation class from a factory. There should be no runtime >> dependency on the OSGi framework. >> >> Are there any good examples out there that I could try to emulate? >> >> If not, can anybody provide me with some advice? >> >> My thought is to have: >> >> 1. A public api package (for all cases) >> 2. A private “factory” package (which for OSGi users would just be >> private and ignored, and for non-OSGi users would be the part of the >> library they would use to obtain the service class), and >> 3. An “internal” package that includes an Activator (in an OSGi >> environment this would provide the service implementation, for non-OSGi >> users it would be ignored). >> >> >> Thanks so much!! >> >> Cheers, >> =David >> >> >> _______________________________________________ >> 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 > > _______________________________________________ > OSGi Developer Mail List > osgi-dev@mail.osgi.org > https://mail.osgi.org/mailman/listinfo/osgi-dev -- *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile> (@rotty3000) Senior Software Architect *Liferay, Inc.* <http://www.liferay.com> (@Liferay)
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev