Good one Tim! Oh, and I forgot to show that the "controller" component should be immediate otherwise it will never activate since nothing should "use" it.
- Ray On Mon, May 1, 2017 at 1:31 PM, Tim Ward <tim.w...@paremus.com> wrote: > For a dynamic import your controller could register a listener so that > when a suitable package appears in the runtime your disabled component gets > activated without needing to restart the controller. > > Tim > > Sent from my iPhone > > On 1 May 2017, at 17:41, Raymond Auge <raymond.a...@liferay.com> wrote: > > Hey All, > I managed to find a relatively elegant solution to this with pure DS. > > Given a component using an optional/dynamic package(s): > > import com.liferay.demo.foo.Foo; // The optional package > @Component( > enabled = false // disable so that DS ignores it > ) > public class OptionalPackageConsumer implements Foo {...} > > A controller is created which does the classloader check: > > @Component > public class OptionalPackageConsumerStarter { > @Activate > void activate(ComponentContext componentContext) { > try { > Class.forName(com.liferay.demo.foo.Foo.class.getName()); > > componentContext.enableComponent( > OptionalPackageConsumer.class.getName()); > } > catch (Throwable t) { > _log.warn("Could not find {}", t.getMessage()); > } > } > } > > If successful, the component is enabled, otherwise, don't! > > - Ray > > > > On Thu, Apr 27, 2017 at 1:48 AM, Fauth Dirk (AA-AS/EIS2-EU) < > dirk.fa...@de.bosch.com> wrote: > >> I totally agree that a clean solution would be to extract the service in >> another bundle with a non optional dependency, as this avoids any runtime >> issues at the beginning by not starting the bundle. Will think about that >> for the Platform Runtime after Oxygen, as such a change is not allowed at >> the current state of the development. >> >> >> >> Nevertheless I created https://bugs.eclipse.org/bugs/ >> show_bug.cgi?id=515873 because the NPE is misleading. Whether an >> exception should be shown or not is discussable. Felix is not showing >> anything at all, which also makes it hard to find the reason why the >> service is not activated. Therefore logging the exception is perfectly fine >> in my opinion. But the NPE when using the field strategy looks incorrect to >> me. It doesn’t help anyway to find the real cause. >> >> >> >> Mit freundlichen Grüßen / Best regards >> >> >> *Dirk Fauth * >> Automotive Service Solutions, ESI application (AA-AS/EIS2-EU) >> Robert Bosch GmbH | Postfach 11 29 | 73201 Plochingen | GERMANY | >> www.bosch.com >> Tel. +49(7153)666-1155 <+49%207153%206661155> | dirk.fa...@de.bosch.com >> >> Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart, HRB 14000; >> Aufsichtsratsvorsitzender: Franz Fehrenbach; Geschäftsführung: Dr. >> Volkmar Denner, >> Prof. Dr. Stefan Asenkerschbaumer, Dr. Rolf Bulander, Dr. Stefan Hartung, >> Dr. Markus Heyn, Dr. Dirk Hoheisel, >> Christoph Kübel, Uwe Raschke, Peter Tyroller >> >> >> *Von:* osgi-dev-boun...@mail.osgi.org [mailto:osgi-dev-bounces@mail. >> osgi.org] *Im Auftrag von *Thomas Watson >> *Gesendet:* Mittwoch, 26. April 2017 14:38 >> *An:* osgi-dev@mail.osgi.org >> >> *Betreff:* Re: [osgi-dev] handling optional/dynamic imports in DS >> >> >> >> By Private-Package Peter means he packages the optional package >> internally in the bundle but also optionally imports it so that if it is >> resolved to an external provider then that will be used over the internal >> copy. The Private-Package header in bnd will instruct bnd to package the >> package internally in the jar. >> >> >> >> Personally, if I had this scenario I would extract the service component >> out to a new bundle that has a non-optional import for the package and be >> done with the magic of dynamic or optional imports. Or if that is not what >> you want I would make it a fragment the that has a non-optional import. >> That way the bundle with the service component cannot possibly provide its >> service component until it is resolved. >> >> >> >> I'm not sure I follow your example that is failing in equinox, but open a >> bug if you find it is an Equinox bug. >> >> >> Tom >> >> >> >> >> >> >> ----- Original message ----- >> From: "Fauth Dirk (AA-AS/EIS2-EU)" <dirk.fa...@de.bosch.com> >> Sent by: osgi-dev-boun...@mail.osgi.org >> To: OSGi Developer Mail List <osgi-dev@mail.osgi.org> >> Cc: >> Subject: Re: [osgi-dev] handling optional/dynamic imports in DS >> Date: Wed, Apr 26, 2017 3:02 AM >> >> >> Interestingly this works fine when running from Bndtools with Felix. >> >> >> >> If I try the same with Equinox for projects created with PDE I get a >> NullPointerException. IIRC Private-Package is something special to Bnd. Is >> that correct? I wonder if that exception is caused by some PDE flaws or if >> it is an issue in Equinox Oxygen. In both cases Apache Felix SCR 2.0 is >> used. (in Oxygen 2.0.8 and in Bndtools 2.0.2) >> >> >> >> *org.osgi.framework.ServiceException*: Exception in >> org.apache.felix.scr.impl.manager.SingleComponentManager.getService() >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse. >> factoryGetService(*ServiceFactoryUse.java:222*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse. >> getService(*ServiceFactoryUse.java:111*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceConsumer$2. >> getService(*ServiceConsumer.java:45*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceRegistratio >> nImpl.getService(*ServiceRegistrationImpl.java:508*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry. >> getService(*ServiceRegistry.java:461*) >> >> at org.eclipse.osgi.internal.framework.BundleContextImpl.getSer >> vice(*BundleContextImpl.java:624*) >> >> at org.apache.felix.scr.impl.manager.SingleRefPair.getServiceOb >> ject(*SingleRefPair.java:72*) >> >> at org.apache.felix.scr.impl.inject.FieldHandler$ReferenceMetho >> dImpl.getServiceObject(*FieldHandler.java:985*) >> >> at org.apache.felix.scr.impl.manager.DependencyManager.getServi >> ceObject(*DependencyManager.java:2201*) >> >> at org.apache.felix.scr.impl.manager.DependencyManager$Multiple >> StaticReluctantCustomizer.prebind(*DependencyManager.java:699*) >> >> at org.apache.felix.scr.impl.manager.DependencyManager.prebind( >> *DependencyManager.java:1520*) >> >> at org.apache.felix.scr.impl.manager.AbstractComponentManager.c >> ollectDependencies(*AbstractComponentManager.java:1006*) >> >> at org.apache.felix.scr.impl.manager.SingleComponentManager.get >> ServiceInternal(*SingleComponentManager.java:859*) >> >> at org.apache.felix.scr.impl.manager.SingleComponentManager.get >> Service(*SingleComponentManager.java:823*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse$ >> 1.run(*ServiceFactoryUse.java:212*) >> >> at java.security.AccessController.doPrivileged(*Native Method*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse. >> factoryGetService(*ServiceFactoryUse.java:210*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse. >> getService(*ServiceFactoryUse.java:111*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceConsumer$2. >> getService(*ServiceConsumer.java:45*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceRegistratio >> nImpl.getService(*ServiceRegistrationImpl.java:508*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry. >> getService(*ServiceRegistry.java:461*) >> >> at org.eclipse.osgi.internal.framework.BundleContextImpl.getSer >> vice(*BundleContextImpl.java:624*) >> >> at org.apache.felix.gogo.runtime.CommandProxy.getTarget( >> *CommandProxy.java:50*) >> >> at org.apache.felix.gogo.runtime.CommandProxy.execute( >> *CommandProxy.java:72*) >> >> at org.apache.felix.gogo.runtime.Closure.executeCmd( >> *Closure.java:477*) >> >> at org.apache.felix.gogo.runtime.Closure.executeStatement( >> *Closure.java:403*) >> >> at org.apache.felix.gogo.runtime.Pipe.run(*Pipe.java:108*) >> >> at org.apache.felix.gogo.runtime.Closure.execute( >> *Closure.java:183*) >> >> at org.apache.felix.gogo.runtime.Closure.execute( >> *Closure.java:120*) >> >> at org.apache.felix.gogo.runtime.CommandSessionImpl.execute( >> *CommandSessionImpl.java:89*) >> >> at org.apache.felix.gogo.shell.Console.run(*Console.java:62*) >> >> at org.apache.felix.gogo.shell.Shell.console(*Shell.java:203*) >> >> at org.apache.felix.gogo.shell.Shell.gosh(*Shell.java:128*) >> >> at sun.reflect.NativeMethodAccessorImpl.invoke0(*Native Method*) >> >> at sun.reflect.NativeMethodAccessorImpl.invoke( >> *NativeMethodAccessorImpl.java:62*) >> >> at sun.reflect.DelegatingMethodAccessorImpl.invoke( >> *DelegatingMethodAccessorImpl.java:43*) >> >> at java.lang.reflect.Method.invoke(*Method.java:498*) >> >> at org.apache.felix.gogo.runtime.Reflective.invoke( >> *Reflective.java:137*) >> >> at org.apache.felix.gogo.runtime.CommandProxy.execute( >> *CommandProxy.java:82*) >> >> at org.apache.felix.gogo.runtime.Closure.executeCmd( >> *Closure.java:477*) >> >> at org.apache.felix.gogo.runtime.Closure.executeStatement( >> *Closure.java:403*) >> >> at org.apache.felix.gogo.runtime.Pipe.run(*Pipe.java:108*) >> >> at org.apache.felix.gogo.runtime.Closure.execute( >> *Closure.java:183*) >> >> at org.apache.felix.gogo.runtime.Closure.execute( >> *Closure.java:120*) >> >> at org.apache.felix.gogo.runtime.CommandSessionImpl.execute( >> *CommandSessionImpl.java:89*) >> >> at org.apache.felix.gogo.shell.Activator.run(*Activator.java:75*) >> >> at java.lang.Thread.run(*Thread.java:745*) >> >> Caused by: *java.lang.NullPointerException* >> >> at org.apache.felix.scr.impl.inject.FieldHandler.validateField( >> *FieldHandler.java:279*) >> >> at org.apache.felix.scr.impl.inject.FieldHandler.access$500( >> *FieldHandler.java:51*) >> >> at org.apache.felix.scr.impl.inject.FieldHandler$NotResolved. >> resolve(*FieldHandler.java:839*) >> >> at org.apache.felix.scr.impl.inject.FieldHandler$NotResolved. >> fieldExists(*FieldHandler.java:864*) >> >> at org.apache.felix.scr.impl.inject.FieldHandler.fieldExists( >> *FieldHandler.java:918*) >> >> at org.apache.felix.scr.impl.inject.FieldHandler$3.init( >> *FieldHandler.java:1018*) >> >> at org.apache.felix.scr.impl.manager.DependencyManager.invokeIn >> itMethod(*DependencyManager.java:1657*) >> >> at org.apache.felix.scr.impl.manager.DependencyManager.open( >> *DependencyManager.java:1533*) >> >> at org.apache.felix.scr.impl.manager.SingleComponentManager.cre >> ateImplementationObject(*SingleComponentManager.java:261*) >> >> at org.apache.felix.scr.impl.manager.SingleComponentManager.cre >> ateComponent(*SingleComponentManager.java:109*) >> >> at org.apache.felix.scr.impl.manager.SingleComponentManager.get >> Service(*SingleComponentManager.java:906*) >> >> at org.apache.felix.scr.impl.manager.SingleComponentManager.get >> ServiceInternal(*SingleComponentManager.java:879*) >> >> at org.apache.felix.scr.impl.manager.SingleComponentManager.get >> Service(*SingleComponentManager.java:823*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse$ >> 1.run(*ServiceFactoryUse.java:212*) >> >> at java.security.AccessController.doPrivileged(*Native Method*) >> >> at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse. >> factoryGetService(*ServiceFactoryUse.java:210*) >> >> ... 46 more >> >> >> >> Mit freundlichen Grüßen / Best regards >> >> *Dirk Fauth* >> >> Automotive Service Solutions, ESI application (AA-AS/EIS2-EU) >> Robert Bosch GmbH | Postfach 11 29 | 73201 Plochingen | GERMANY | >> www.bosch.com >> Tel. +49(7153)666-1155 <+49%207153%206661155> | dirk.fa...@de.bosch.com >> >> Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart, HRB 14000; >> Aufsichtsratsvorsitzender: Franz Fehrenbach; Geschäftsführung: Dr. >> Volkmar Denner, >> Prof. Dr. Stefan Asenkerschbaumer, Dr. Rolf Bulander, Dr. Stefan Hartung, >> Dr. Markus Heyn, Dr. Dirk Hoheisel, >> Christoph Kübel, Uwe Raschke, Peter Tyroller >> >> *Von:* osgi-dev-boun...@mail.osgi.org [mailto:osgi-dev-bounces@mail. >> osgi.org <osgi-dev-boun...@mail.osgi.org>] *Im Auftrag von *Peter Kriens >> *Gesendet:* Mittwoch, 26. April 2017 09:14 >> *An:* OSGi Developer Mail List <osgi-dev@mail.osgi.org> >> *Betreff:* Re: [osgi-dev] handling optional/dynamic imports in DS >> >> >> >> I used to import the package optional and then provide it as an internal >> Private-Package. The import has priority but the internal package is used >> when the import fails to resolve. Since you’re then always wired to a >> package you can handle dependencies on the place they should be handled: >> services. >> >> >> >> This keeps everybody happy internally for very little cost. I’ve included >> a bndtools/enRoute example. >> >> >> >> Kind regards, >> >> >> >> Peter Kriens >> >> >> >> >> >> ————————————————— bnd.bnd >> >> Private-Package: \ >> >> org.osgi.service.cm,\ >> >> com.foo.provider >> >> >> >> Import-Package: \ >> >> org.osgi.service.cm;resolution:=optional,\ >> >> * >> >> >> >> -buildpath: \ >> >> osgi.enroute.base.api >> >> -runrequires: \ >> >> osgi.identity;filter:='(osgi.i >> dentity=com.foo.provider)',\ >> >> osgi.identity;filter:='(osgi.i >> dentity=org.apache.felix.gogo.runtime)',\ >> >> osgi.identity;filter:='(osgi.i >> dentity=org.apache.felix.gogo.shell)',\ >> >> osgi.identity;filter:='(osgi.i >> dentity=org.apache.felix.gogo.command)' >> >> -runbundles: \ >> >> com.foo.provider;version=snapshot,\ >> >> org.apache.felix.log;version='[1.0.1,1.0.2)',\ >> >> org.apache.felix.scr;version='[2.0.2,2.0.3)',\ >> >> org.apache.felix.gogo.runtime,\ >> >> org.apache.felix.gogo.shell;version=0.16 >> >> >> >> ————————————————— com.foo.provider.Optional >> >> @Component >> >> public class Optional >> >> { >> >> @Reference(cardinality=ReferenceCardinality.OPTIONAL) >> >> ConfigurationAdmin admin; >> >> >> >> @Activate >> >> void activate() { >> >> System.out.println("activate " + admin); >> >> } >> >> } >> >> >> >> On 25 Apr 2017, at 23:10, Raymond Auge <raymond.a...@liferay.com> wrote: >> >> >> >> I'm wondering if there is a reasonable model for handling optional or >> dynamic package imports in DS. >> >> While optionality at the package level is not an ideal model, sometimes >> it can't be avoided. >> >> I'd like to know if others have come across a "reasonable" way to model >> this in DS. >> >> >> >> Sincerely, >> >> -- >> >> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile> >> (@rotty3000) >> >> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com/> >> (@Liferay) >> >> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org/> >> (@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 >> >> >> >> >> >> _______________________________________________ >> 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) > Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> > (@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 > -- *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile> (@rotty3000) Senior Software Architect *Liferay, Inc.* <http://www.liferay.com> (@Liferay) Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev