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 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.

Reply via email to