Hi Stephan, Yes, that makes sense.
According to the specification, region context's bundleContext was meant for this: Typically the Region's context bundle would be used to obtain a bundle > context with the getBundleContext() method, which has a perspective as a > constituent of the Region. This is useful in the following ways: > > - Implementing Subsystem aware extenders. Such extenders need to be > able to register listeners and monitor the inside of a Region in order to > react to the constituent bundles of a Region. > - Monitoring of internal events. > > Also relevant: https://www.mail-archive.com/[email protected]/msg01207.html Getting region's bundle context would require introducing a dependency on org.osgi.service.subsystem.Subsystem though, breaking the project for containers without Subsystem :-/. Regards, Jaseem On Thursday, May 24, 2018 at 5:42:49 PM UTC+5:30, Stephan Siano wrote: > > Hi Jaseem, > > If you use the region context bundle for the extender, the extender will > extend its own region and its children, but it will not reach out of the > region. From my perspective this would be the correct semantics for scoped > subsystems, but I am not an expert here. > > Let's assume the following region graph: > > root - A > | > B - C > > (the root region has two child regions (A and B) and B has a child region > C) > > An extender, which registers itself with the region context bundle's > context, will extend bundles in region B and C, but not in root or A. An > extender which registers in the root context would extend all contexts (but > it must be in the root context). > > Does this make sense? > > Best regards > Stephan > > Am Donnerstag, 24. Mai 2018 09:02:32 UTC+2 schrieb Jaseem: >> >> I was doing some reading myself following Christoph's argument. Should an >> extender be aware of events inside a subsystem at all? is it correct >> semantic for information to leak out of the region? >> >> On Thu 24 May, 2018, 12:02 PM Stephan Siano, <[email protected]> wrote: >> >>> Hi, >>> >>> I had a look into the OSGi enterprise spec (134.9). It says that the >>> bundle context of the region context bundle is supposed to be used for >>> subsystem aware extenders, so the idea of implementing this would be to >>> register the bundle listener for the web extender with the region context >>> bundle's bundleContext if bundle 0 is unreachable. >>> >>> Best regards >>> Stephan >>> >>> Am Mittwoch, 23. Mai 2018 15:20:59 UTC+2 schrieb Stephan Siano: >>>> >>>> Hi, >>>> >>>> One problem with the bundleContext.getBundle(0) call is that it will >>>> return null if pax web is not running in the root subsystem, in that case >>>> the region context would be required instead. >>>> >>>> Concerning the composite subsystems: >>>> What happens if the composite subsystem exports servlets and filters >>>> according to the Whiteboard pattern? That should work if a scoped >>>> subsystem >>>> exports a service that can be accessed by the whiteboard extender. >>>> >>>> What would be a sensible semantics of a war extender in combination >>>> with scoped subsystems? >>>> >>>> Best regards >>>> Stephan >>>> >>>> Am Mittwoch, 23. Mai 2018 13:14:50 UTC+2 schrieb Jaseem: >>>>> >>>>> The subsystem we are using is of type COMPOSITE. That means we would >>>>> like these subsystem ESAs to use some of our common components and >>>>> pax.web >>>>> is one of them. We mean to share the core components like pax.web, apace >>>>> camel to be reusable. Thats our use case. >>>>> >>>>> On Wednesday, May 23, 2018 at 3:23:23 PM UTC+5:30, Jaseem wrote: >>>>>> >>>>>> Hello, >>>>>> >>>>>> Currently pax web extenders are not subsystem-aware. The extenders >>>>>> use BundleTracker/ServiceTracker on their own BundleContext. Events in >>>>>> scoped subsystems are not visible to these BundleContexts, hence Web >>>>>> bundles inside such subsystems don't get registered. >>>>>> >>>>>> We can solve this by tracking on the system bundle context similar to >>>>>> this: >>>>>> >>>>>> systemBundleContext = context.getBundle(0).getBundleContext(); >>>>>> systemBundleContext.addBundleListener(this); >>>>>> this.tracker = new BundleTracker<>(systemBundleContext, Bundle.ACTIVE >>>>>> | Bundle.STARTING, this); >>>>>> >>>>>> This is similar to >>>>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=514636 >>>>>> and https://issues.apache.org/jira/browse/CAMEL-8647 . >>>>>> >>>>>> I am currently on the activity of making WAR extender subsystem aware >>>>>> and I'm getting this exception when the WAR bundle is started/restarted: >>>>>> >>>>>> java.lang.ClassNotFoundException: testWebPackage.testServlet >>>>>> at java.net.URLClassLoader.findClass(URLClassLoader.java:443) >>>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:490) >>>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:423) >>>>>> at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1927) >>>>>> at >>>>>> org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:978) >>>>>> at org.apache.felix.framework.Felix.loadClass(Felix.java:106) >>>>>> at >>>>>> org.ops4j.pax.swissbox.core.BundleClassLoader.findClass(BundleClassLoader.java:176) >>>>>> at >>>>>> org.ops4j.pax.swissbox.core.BundleClassLoader.loadClass(BundleClassLoader.java:194) >>>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:423) >>>>>> at >>>>>> org.ops4j.pax.web.service.spi.model.ServletModel.getServletFromName(ServletModel.java:232) >>>>>> at >>>>>> org.ops4j.pax.web.service.tomcat.internal.TomcatServerWrapper.addServlet(TomcatServerWrapper.java:348) >>>>>> at >>>>>> org.ops4j.pax.web.service.tomcat.internal.ActiveServerState.addServlet(ActiveServerState.java:114) >>>>>> at >>>>>> org.ops4j.pax.web.service.tomcat.internal.TomcatServerController.addServlet(TomcatServerController.java:114) >>>>>> at >>>>>> org.ops4j.pax.web.service.internal.HttpServiceStarted.registerServlet(HttpServiceStarted.java:245) >>>>>> at >>>>>> org.ops4j.pax.web.service.internal.HttpServiceStarted.registerServlet(HttpServiceStarted.java:471) >>>>>> at >>>>>> org.ops4j.pax.web.service.internal.HttpServiceProxy.registerServlet(HttpServiceProxy.java:520) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.RegisterWebAppVisitorWC.visit(RegisterWebAppVisitorWC.java:261) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.model.WebApp.accept(WebApp.java:644) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.WebAppPublisher$WebAppDependencyListener.register(WebAppPublisher.java:227) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.WebAppPublisher$WebAppDependencyListener.addingService(WebAppPublisher.java:172) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.WebAppPublisher$WebAppDependencyListener.addingService(WebAppPublisher.java:128) >>>>>> at >>>>>> org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:941) >>>>>> at >>>>>> org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:870) >>>>>> at >>>>>> org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256) >>>>>> at >>>>>> org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183) >>>>>> at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:318) >>>>>> at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:261) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.WebAppPublisher.publish(WebAppPublisher.java:97) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.WebObserver.deploy(WebObserver.java:217) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.WebObserver$1.doStart(WebObserver.java:172) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.extender.SimpleExtension.start(SimpleExtension.java:59) >>>>>> at >>>>>> org.ops4j.pax.web.extender.war.internal.extender.AbstractExtender.lambda$createExtension$0(AbstractExtender.java:269) >>>>>> at >>>>>> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) >>>>>> at java.util.concurrent.FutureTask.run(FutureTask.java:266) >>>>>> >>>>>> Any help towards analyzing or resolving this exception is appreciated. >>>>>> >>>>>> The structure is like this testSubsystem -> testWebBundle >>>>>> ->testWebPackage. testSubsystem is a composite subsystem. >>>>>> >>>>>> Changes made by me are: >>>>>> >>>>>> AbstractExtender: >>>>>> protected BundleContext systemBundleContext; >>>>>> >>>>>> public void start(BundleContext context) throws Exception { >>>>>> bundleContext = context; >>>>>> systemBundleContext = context.getBundle(0).getBundleContext(); >>>>>> systemBundleContext.addBundleListener(this); >>>>>> this.tracker = new BundleTracker<>(systemBundleContext, Bundle. >>>>>> ACTIVE >>>>>> | Bundle.STARTING, this); >>>>>> if (!this.synchronous) { >>>>>> this.executors = createExecutor(); >>>>>> } >>>>>> doStart(); >>>>>> >>>>>> >>>>>> } >>>>>> >>>>>> Activator: >>>>>> @Override >>>>>> protected void doStart() throws Exception { >>>>>> logger.debug("Pax Web WAR Extender - Starting"); >>>>>> >>>>>> webEventDispatcher = new WebEventDispatcher(systemBundleContext); >>>>>> >>>>>> Filter filterPackage = >>>>>> systemBundleContext.createFilter("(objectClass=org.osgi.service.packageadmin.Package >>>>>> >>>>>> Admin)"); >>>>>> packageAdminTracker = new ServiceTracker<>(systemBundleContext, >>>>>> filterPackage, null); >>>>>> packageAdminTracker.open(); >>>>>> >>>>>> DefaultWebAppDependencyManager dependencyManager = new >>>>>> DefaultWebAppDependencyManager(systemBundleContext); >>>>>> >>>>>> webObserver = new WebObserver(new WebAppParser(packageAdminTracker), >>>>>> new WebAppPublisher(webEventDispatcher, systemBundleContext), >>>>>> webEventDispatcher, dependencyManager, >>>>>> systemBundleContext); >>>>>> >>>>>> startTracking(); >>>>>> registration = getBundleContext().registerService( >>>>>> WarManager.class, webObserver, >>>>>> new Hashtable<>()); >>>>>> >>>>>> logger.debug("Pax Web WAR Extender - Started"); >>>>>> } >>>>>> >>>>>> WebAppPublisher: >>>>>> >>>>>> public void publish(final WebApp webApp) { >>>>>> NullArgumentException.validateNotNull(webApp, "Web app"); >>>>>> LOG.debug("Publishing web application [{}]", webApp); >>>>>> final BundleContext systemBundleContext = bundleContext.getBundle(0 >>>>>> ).getBundleContext(); >>>>>> if (systemBundleContext != null) { >>>>>> try { >>>>>> Filter filter = systemBundleContext.createFilter(String.format( >>>>>> "(&(objectClass=%s)(bundle.id=%d))", >>>>>> WebAppDependencyHolder.class.getName(), webApp >>>>>> .getBundle().getBundleId())); >>>>>> ServiceTracker<WebAppDependencyHolder, WebAppDependencyHolder> >>>>>> dependencyTracker = new ServiceTracker<WebAppDependencyHolder, >>>>>> WebAppDependencyHolder>( >>>>>> systemBundleContext, filter, >>>>>> new WebAppDependencyListener(webApp, eventDispatcher, >>>>>> bundleContext)); >>>>>> webApps.put(webApp, dependencyTracker); >>>>>> dependencyTracker.open(); >>>>>> } catch (InvalidSyntaxException exc) { >>>>>> throw new IllegalArgumentException(exc); >>>>>> } >>>>>> } else { >>>>>> LOG.warn("Bundle context could not be discovered for bundle [" >>>>>> + webApp.getBundle() + "]" >>>>>> + "Skipping publishing of web application [" + webApp + "]"); >>>>>> } >>>>>> } >>>>>> >>>>>> DefaultWebAppDependencyManager: >>>>>> private final BundleContext systemBundleContext; >>>>>> >>>>>> public DefaultWebAppDependencyManager(BundleContext >>>>>> systemBundleContext) { >>>>>> this.systemBundleContext = systemBundleContext; >>>>>> this.trackers = new ConcurrentHashMap<>(); >>>>>> this.services = new ConcurrentHashMap<>(); >>>>>> } >>>>>> >>>>>> public void addWebApp(final WebApp webApp) { >>>>>> ReplaceableService<HttpService> tracker = new ReplaceableService<>( >>>>>> systemBundleContext, HttpService.class, new >>>>>> ReplaceableServiceListener<HttpService>() { >>>>>> @Override >>>>>> public void serviceChanged(HttpService oldService, HttpService >>>>>> newService) { >>>>>> ServiceRegistration<WebAppDependencyHolder> oldReg; >>>>>> ServiceRegistration<WebAppDependencyHolder> newReg; >>>>>> if (newService != null) { >>>>>> WebAppDependencyHolder holder = new DefaultWebAppDependencyHolder( >>>>>> newService); >>>>>> Dictionary<String, String> props = new Hashtable<>(); >>>>>> props.put("bundle.id", Long.toString(webApp.getBundle().getBundleId >>>>>> ())); >>>>>> newReg = systemBundleContext.registerService(WebAppDependencyHolder. >>>>>> class, holder, props); >>>>>> } else { >>>>>> newReg = null; >>>>>> } >>>>>> >>>>>> >>>>>> -- >>> -- >>> ------------------ >>> OPS4J - http://www.ops4j.org - [email protected] >>> >>> --- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "OPS4J" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/ops4j/a7aglTTLAwQ/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- -- ------------------ OPS4J - http://www.ops4j.org - [email protected] --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
