From 76df005c64b40c750362834eb1902049bd9d81c2 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 11 Apr 2013 10:22:44 +1000 Subject: [PATCH] 405119 Tidy up comments and code formatting for osgi --- ...gableWebAppRegistrationCustomizerImpl.java | 89 +++------ .../WebappRegistrationCustomizerImpl.java | 3 + .../osgi/boot/AbstractContextProvider.java | 9 +- .../jetty/osgi/boot/AbstractOSGiApp.java | 5 +- .../osgi/boot/AbstractWebAppProvider.java | 12 +- .../osgi/boot/BundleContextProvider.java | 3 +- .../jetty/osgi/boot/BundleProvider.java | 5 + .../osgi/boot/JettyBootstrapActivator.java | 153 ++------------- .../eclipse/jetty/osgi/boot/OSGiDeployer.java | 4 +- .../osgi/boot/OSGiMetaInfConfiguration.java | 7 + .../jetty/osgi/boot/OSGiServerConstants.java | 2 + .../jetty/osgi/boot/OSGiUndeployer.java | 4 +- .../jetty/osgi/boot/OSGiWebappConstants.java | 7 +- .../osgi/boot/ServiceContextProvider.java | 4 +- .../jetty/osgi/boot/ServiceProvider.java | 5 + .../osgi/boot/ServiceWebAppProvider.java | 1 - .../DefaultJettyAtJettyHomeHelper.java | 21 +- .../JettyServerServiceTracker.java | 7 +- .../JettyContextHandlerServiceTracker.java | 11 +- .../webapp/LibExtClassLoaderHelper.java | 38 +--- .../webapp/OSGiWebappClassLoader.java | 20 +- .../webapp/WebBundleTrackerCustomizer.java | 179 ++++++++++++------ .../osgi/boot/utils/OSGiClassLoader.java | 3 +- .../utils/WebappRegistrationCustomizer.java | 26 +-- .../DefaultBundleClassLoaderHelper.java | 3 + .../internal/DefaultFileLocatorHelper.java | 3 + .../internal/PackageAdminServiceTracker.java | 3 + 27 files changed, 263 insertions(+), 364 deletions(-) diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/PluggableWebAppRegistrationCustomizerImpl.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/PluggableWebAppRegistrationCustomizerImpl.java index 2521ed186dd..2036eb9800b 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/PluggableWebAppRegistrationCustomizerImpl.java +++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/PluggableWebAppRegistrationCustomizerImpl.java @@ -21,8 +21,6 @@ package org.eclipse.jetty.osgi.boot.jasper; import java.io.File; import java.net.URL; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -36,61 +34,37 @@ import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; + + /** - * Plug bundles that contains tld files so that jasper will discover them and - * set them up in jetty. + * PluggableWebAppRegistrationCustomizerImpl * - * For example: - * -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet - * ,com.opensymphony.module.sitemesh Otherwise use an attribute to the - * WebAppDeployer <New - * class="org.eclipse.jetty.deploy.providers.WebAppProvider"> .... <Set - * name="tldBundles"><Property name="org.eclipse.jetty.osgi.tldsbundles" - * default="" /></Set> <New> + * + * Use a System property to define bundles that contain tlds that need to + * be treated by jasper as if they were on the jetty container's classpath. + * + * The bundle locations are converted to URLs for jasper's use. + * + * Eg: + * -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh */ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistrationCustomizer { /** - * To plug into jasper bundles that contain tld files please use a list of - * bundle's symbolic names: - * -Djetty.osgi.tldbundles=org.springframework.web.servlet - * ,com.opensymphony.module.sitemesh + * Comma separated list of names of bundles that contain tld files that should be + * discoved by jasper as if they were on the container's classpath. + * Eg: + * -Djetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh */ public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles"; + + /** - * Union of the tld bundles defined system wide and the one defines as an - * attribute of the AppProvider. + * Check the System property "org.eclipse.jetty.osgi.tldbundles" for names of + * bundles that contain tlds and convert to URLs. * - * @param provider - * @return - */ - private static Collection getTldBundles(DeploymentManager deploymentManager) - { - String sysprop = System.getProperty(SYS_PROP_TLD_BUNDLES); - String att = (String) deploymentManager.getContextAttribute(OSGiWebInfConfiguration.CONTAINER_BUNDLE_PATTERN); - if (sysprop == null && att == null) { return Collections.emptySet(); } - if (att == null) - { - att = sysprop; - } - else if (sysprop != null) - { - att = att + "," + sysprop; - } - - Collection tldbundles = new HashSet(); - StringTokenizer tokenizer = new StringTokenizer(att, ", \n\r\t", false); - while (tokenizer.hasMoreTokens()) - { - tldbundles.add(tokenizer.nextToken()); - } - return tldbundles; - } - - /** - * @return The location of the jars that contain tld files. Jasper will - * discover them. + * @return The location of the jars that contain tld files as URLs. */ public URL[] getJarsWithTlds(DeploymentManager deploymentManager, BundleFileLocatorHelper locatorHelper) throws Exception { @@ -118,10 +92,10 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra for (Bundle bundle : bundles) { if (sysNames.contains(bundle.getSymbolicName())) - registerTldBundle(locatorHelper, bundle, urls); + convertBundleLocationToURL(locatorHelper, bundle, urls); if (pattern != null && pattern.matcher(bundle.getSymbolicName()).matches()) - registerTldBundle(locatorHelper, bundle, urls); + convertBundleLocationToURL(locatorHelper, bundle, urls); } return urls.toArray(new URL[urls.size()]); @@ -129,19 +103,8 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra } /** - * Resolves the bundle that contains tld files as a set of URLs that will be - * passed to jasper as a URLClassLoader later on. Usually that would be a - * single URL per bundle. But we do some more work if there are jars - * embedded in the bundle. - * - * The jasper TldScanner expects a URLClassloader to parse a jar for the - * /META-INF/*.tld it may contain. We place the bundles that we know contain - * such tag-libraries. Please note that it will work if and only if the - * bundle is a jar (!) Currently we just hardcode the bundle that contains - * the jstl implemenation. - * - * A workaround when the tld cannot be parsed with this method is to copy - * and paste it inside the WEB-INF of the webapplication where it is used. + * Resolves a bundle that contains tld files as a URL. The URLs are + * used by jasper to discover the tld files. * * Support only 2 types of packaging for the bundle: - the bundle is a jar * (recommended for runtime.) - the bundle is a folder and contain jars in @@ -153,7 +116,7 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra * @param urls * @throws Exception */ - private void registerTldBundle(BundleFileLocatorHelper locatorHelper, Bundle bundle, Set urls) throws Exception + private void convertBundleLocationToURL(BundleFileLocatorHelper locatorHelper, Bundle bundle, Set urls) throws Exception { File jasperLocation = locatorHelper.getBundleInstallLocation(bundle); if (jasperLocation.isDirectory()) @@ -181,7 +144,5 @@ public class PluggableWebAppRegistrationCustomizerImpl implements WebappRegistra { urls.add(jasperLocation.toURI().toURL()); } - } - } \ No newline at end of file diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java index 7b744b99cd3..9212e425511 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java +++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/WebappRegistrationCustomizerImpl.java @@ -44,6 +44,9 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** + * + * WebappRegistrationCustomizerImpl + * * Fix various shortcomings with the way jasper parses the tld files. Plugs the * JSTL tlds assuming that they are packaged with the bundle that contains the * JSTL classes. diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java index 6f07480ab6b..afb831361fd 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java @@ -22,14 +22,12 @@ import java.io.File; import java.net.URL; import java.util.Dictionary; import java.util.HashMap; -import java.util.Hashtable; import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.osgi.boot.utils.EventSender; import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; @@ -37,11 +35,8 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarResource; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceRegistration; @@ -49,7 +44,9 @@ import org.osgi.framework.ServiceRegistration; /** * AbstractContextProvider * - * + * Base class for DeploymentManager Providers that can deploy ContextHandlers into + * Jetty that have been discovered via OSGI either as bundles or services. + * */ public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java index be09d2cfd69..b9e040b128a 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractOSGiApp.java @@ -32,9 +32,10 @@ import org.osgi.framework.ServiceRegistration; /** - * AbstractBundleApp - * + * AbstractOSGiApp * + * Base class representing info about a webapp/ContextHandler that is deployed into Jetty. + * */ public abstract class AbstractOSGiApp extends App { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java index 73da20f41c1..7a854c7dbaf 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java @@ -20,14 +20,9 @@ package org.eclipse.jetty.osgi.boot; import java.io.File; import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppProvider; @@ -35,7 +30,6 @@ import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader; -import org.eclipse.jetty.osgi.boot.utils.EventSender; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; @@ -44,9 +38,7 @@ import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; import org.osgi.service.packageadmin.PackageAdmin; @@ -55,7 +47,9 @@ import org.osgi.service.packageadmin.PackageAdmin; /** * AbstractWebAppProvider * - * + * Base class for Jetty DeploymentManager Providers that are capable of deploying a webapp, + * either from a bundle or an OSGi service. + * */ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implements AppProvider { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java index 149aa99b80b..6ec082e9038 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleContextProvider.java @@ -43,7 +43,7 @@ import org.osgi.framework.ServiceRegistration; /** * BundleContextProvider * - * Handles deploying bundles that define a context xml file for configuring them. + * Handles deploying OSGi bundles that define a context xml file for configuring them. * * */ @@ -136,6 +136,7 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu } apps.add(app); getDeploymentManager().addApp(app); + added = true; } return added; //true if even 1 context from this bundle was added diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java index c87c071bf52..e1372697c00 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/BundleProvider.java @@ -20,6 +20,11 @@ package org.eclipse.jetty.osgi.boot; import org.osgi.framework.Bundle; +/** + * BundleProvider + * + * Jetty DeploymentManager Provider api for webapps or ContextHandlers that are discovered as osgi bundles. + */ public interface BundleProvider { public boolean bundleAdded (Bundle bundle) throws Exception; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java index 2ed6e7bf5e0..2e874bcb253 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/JettyBootstrapActivator.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.osgi.boot; import java.util.Dictionary; import java.util.Hashtable; + import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper; import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker; import org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper; @@ -29,34 +30,33 @@ import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer; import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.BundleTracker; +import org.osgi.util.tracker.ServiceTracker; /** + * JettyBootstrapActivator + * * Bootstrap jetty and publish a default Server instance as an OSGi service. * * Listen for other Server instances to be published as services and support them as deployment targets. * - * Listen for Bundles to be activated, and deploy those that represent webapps to one of the known Server instances. + * Listen for Bundles to be activated, and deploy those that represent webapps/ContextHandlers to one of the known Server instances. * - *
    - *
  1. basic servlet [ok]
  2. - *
  3. basic jetty.xml [ok]
  4. - *
  5. basic jetty.xml and jetty-plus.xml [ok]
  6. - *
  7. basic jsp [ok]
  8. - *
  9. jsp with tag-libs [ok]
  10. - *
  11. test-jndi with atomikos and derby inside ${jetty.home}/lib/ext [ok]
  12. - * */ public class JettyBootstrapActivator implements BundleActivator { - + private static final Logger LOG = Log.getLogger(JettyBootstrapActivator.class); + private static JettyBootstrapActivator INSTANCE = null; public static JettyBootstrapActivator getInstance() @@ -84,7 +84,7 @@ public class JettyBootstrapActivator implements BundleActivator * * @param context */ - public void start(BundleContext context) throws Exception + public void start(final BundleContext context) throws Exception { INSTANCE = this; _bundleContext = context; @@ -102,12 +102,14 @@ public class JettyBootstrapActivator implements BundleActivator context.addServiceListener(_jettyContextHandlerTracker, "(objectclass=" + ContextHandler.class.getName() + ")"); // Create a default jetty instance right now. - DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); + Server defaultServer = DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); - // track Bundles and deploy those that represent webapps to one of the known Servers - WebBundleTrackerCustomizer customizer = new WebBundleTrackerCustomizer(); - _webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, customizer); - customizer.setAndOpenWebBundleTracker(_webBundleTracker); + //Create a bundle tracker to help deploy webapps and ContextHandlers + WebBundleTrackerCustomizer bundleTrackerCustomizer = new WebBundleTrackerCustomizer(); + bundleTrackerCustomizer.setWaitForDefaultServer(defaultServer != null); + _webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, bundleTrackerCustomizer); + bundleTrackerCustomizer.setBundleTracker(_webBundleTracker); + bundleTrackerCustomizer.open(); } /** @@ -120,7 +122,6 @@ public class JettyBootstrapActivator implements BundleActivator { try { - if (_webBundleTracker != null) { _webBundleTracker.close(); @@ -164,122 +165,4 @@ public class JettyBootstrapActivator implements BundleActivator INSTANCE = null; } } - - /** - * Helper method that creates a new org.jetty.webapp.WebAppContext and - * registers it as an OSGi service. The tracker - * {@link JettyContextHandlerServiceTracker} will do the actual deployment. - * - * @param contributor The bundle - * @param webappFolderPath The path to the root of the webapp. Must be a - * path relative to bundle; either an absolute path. - * @param contextPath The context path. Must start with "/" - * @throws Exception - */ - public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath) throws Exception - { - checkBundleActivated(); - WebAppContext contextHandler = new WebAppContext(); - Dictionary dic = new Hashtable(); - dic.put(OSGiWebappConstants.SERVICE_PROP_WAR, webappFolderPath); - dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH, contextPath); - String requireTldBundle = (String) contributor.getHeaders().get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); - if (requireTldBundle != null) - { - dic.put(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE, requireTldBundle); - } - contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic); - } - - /** - * Helper method that creates a new org.jetty.webapp.WebAppContext and - * registers it as an OSGi service. The tracker - * {@link JettyContextHandlerServiceTracker} will do the actual deployment. - * - * @param contributor The bundle - * @param webappFolderPath The path to the root of the webapp. Must be a - * path relative to bundle; either an absolute path. - * @param contextPath The context path. Must start with "/" - * @param dic TODO: parameter description - * @throws Exception - */ - public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath, Dictionary dic) throws Exception - { - checkBundleActivated(); - WebAppContext contextHandler = new WebAppContext(); - dic.put(OSGiWebappConstants.SERVICE_PROP_WAR, webappFolderPath); - dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH, contextPath); - contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic); - } - - /** - * Helper method that creates a new skeleton of a ContextHandler and - * registers it as an OSGi service. The tracker - * {@link JettyContextHandlerServiceTracker} will do the actual deployment. - * - * @param contributor The bundle that registers a new context - * @param contextFilePath The path to the file inside the bundle that - * defines the context. - * @throws Exception - */ - public static void registerContext(Bundle contributor, String contextFilePath) throws Exception - { - registerContext(contributor, contextFilePath, new Hashtable()); - } - - /** - * Helper method that creates a new skeleton of a ContextHandler and - * registers it as an OSGi service. The tracker - * {@link JettyContextHandlerServiceTracker} will do the actual deployment. - * - * @param contributor The bundle that registers a new context - * @param contextFilePath The path to the file inside the bundle that - * defines the context. - * @param dic TODO: parameter description - * @throws Exception - */ - public static void registerContext(Bundle contributor, String contextFilePath, Dictionary dic) throws Exception - { - checkBundleActivated(); - ContextHandler contextHandler = new ContextHandler(); - dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH, contextFilePath); - dic.put(IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE, Boolean.TRUE.toString()); - contributor.getBundleContext().registerService(ContextHandler.class.getName(), contextHandler, dic); - } - - public static void unregister(String contextPath) - { - // todo - } - - /** - * Since org.eclipse.jetty.osgi.boot does not have a lazy activation policy - * when one of the static methods to register a webapp is called we should - * make sure that the bundle is started. - */ - private static void checkBundleActivated() - { - if (INSTANCE == null) - { - Bundle thisBundle = FrameworkUtil.getBundle(JettyBootstrapActivator.class); - try - { - thisBundle.start(); - } - catch (BundleException e) - { - // nevermind. - } - } - } - - /** - * @return The bundle context for this bundle. - */ - public static BundleContext getBundleContext() - { - checkBundleActivated(); - return INSTANCE._bundleContext; - } - } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java index 5f9321ebc9a..1b80e04edd1 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiDeployer.java @@ -27,7 +27,9 @@ import org.eclipse.jetty.osgi.boot.utils.EventSender; /** * OSGiDeployer * - * + * Extension of standard Jetty deployer that emits OSGi EventAdmin + * events whenever a webapp is deployed into OSGi via Jetty. + * */ public class OSGiDeployer extends StandardDeployer { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java index bacc8ea9a03..c67b6bb1f33 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java @@ -32,6 +32,13 @@ import org.eclipse.jetty.webapp.MetaInfConfiguration; import org.eclipse.jetty.webapp.WebAppContext; import org.osgi.framework.Bundle; +/** + * OSGiMetaInfConfiguration + * + * Extension of standard Jetty MetaInfConfiguration class to handle OSGi bundle + * fragments that may also need to be scanned for META-INF info. + * + */ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { private static final Logger LOG = Log.getLogger(OSGiMetaInfConfiguration.class); diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java index 2f9df55ad82..67ef323aee8 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiServerConstants.java @@ -19,6 +19,8 @@ package org.eclipse.jetty.osgi.boot; /** + * OSGiServerConstants + * * Name of the properties that configure a jetty Server OSGi service. */ public class OSGiServerConstants diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java index ac068741d09..674f960b23b 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiUndeployer.java @@ -29,7 +29,9 @@ import org.eclipse.jetty.osgi.boot.utils.EventSender; /** * OSGiUndeployer * - * + * Extension of the Jetty Undeployer which emits OSGi EventAdmin events + * whenever a webapp is undeployed from Jetty. + * */ public class OSGiUndeployer extends StandardUndeployer { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java index 1908eb2de5c..e97457aecdf 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java @@ -19,7 +19,12 @@ package org.eclipse.jetty.osgi.boot; /** - * Name of the service properties for a ContextHandler that configure a webapp deployed on jetty OSGi. + * OSGiWebappConstants + * + * + * Constants (MANIFEST headers, service properties etc) associated with deploying + * webapps into OSGi via Jetty. + * */ public class OSGiWebappConstants { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java index 2e36904fc4f..a228a6288d7 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceContextProvider.java @@ -38,7 +38,9 @@ import org.osgi.framework.ServiceRegistration; /** * ServiceContextProvider * - * + * Jetty DeploymentManager Provider that is able to deploy ContextHandlers discovered via OSGi as services. + * + * */ public class ServiceContextProvider extends AbstractContextProvider implements ServiceProvider { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java index f2304c6b136..34335cf31b0 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceProvider.java @@ -21,6 +21,11 @@ package org.eclipse.jetty.osgi.boot; import org.eclipse.jetty.server.handler.ContextHandler; import org.osgi.framework.ServiceReference; +/** + * ServiceProvider + * + * Jetty DeploymentManager Provider api for webapps or ContextHandlers that are discovered as OSGi services. + */ public interface ServiceProvider { public boolean serviceAdded (ServiceReference ref, ContextHandler handler) throws Exception; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java index e3f97f09132..6008aa033c1 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/ServiceWebAppProvider.java @@ -27,7 +27,6 @@ import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.osgi.boot.utils.EventSender; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java index bef4dcf3731..4c4066b47b2 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java @@ -29,7 +29,6 @@ import java.util.StringTokenizer; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -40,9 +39,12 @@ import org.osgi.framework.BundleContext; * DefaultJettyAtJettyHomeHelper * * + * Creates a default instance of Jetty, based on the values of the + * System properties "jetty.home" or "jetty.home.bundle", one of which + * must be specified in order to create the default instance. + * * Called by the {@link JettyBootstrapActivator} during the starting of the - * bundle. If the system property 'jetty.home' is defined and points to a - * folder, then setup the corresponding jetty server. + * bundle. */ public class DefaultJettyAtJettyHomeHelper { @@ -87,7 +89,7 @@ public class DefaultJettyAtJettyHomeHelper * as part of their properties. *

    */ - public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception + public static Server startJettyAtJettyHome(BundleContext bundleContext) throws Exception { String jettyHomeSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME); String jettyHomeBundleSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME_BUNDLE); @@ -109,7 +111,7 @@ public class DefaultJettyAtJettyHomeHelper if (!jettyHome.exists() || !jettyHome.isDirectory()) { LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp); - return; + return null; } } else if (jettyHomeBundleSysProp != null) @@ -126,14 +128,14 @@ public class DefaultJettyAtJettyHomeHelper if (jettyHomeBundle == null) { LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp); - return; + return null; } } if (jettyHome == null && jettyHomeBundle == null) { LOG.warn("No default jetty created."); - return; + return null; } Server server = new Server(); @@ -152,8 +154,11 @@ public class DefaultJettyAtJettyHomeHelper setProperty(properties, OSGiServerConstants.JETTY_PORT, System.getProperty(OSGiServerConstants.JETTY_PORT)); setProperty(properties, OSGiServerConstants.JETTY_PORT_SSL, System.getProperty(OSGiServerConstants.JETTY_PORT_SSL)); - //register the Server instance as an OSGi service. + //Register the default Server instance as an OSGi service. + //The JettyServerServiceTracker will notice it and configure it. bundleContext.registerService(Server.class.getName(), server, properties); + + return server; } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java index e172c75197e..b946cd8da4b 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java @@ -32,8 +32,11 @@ import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; /** - * Deploy the jetty server instances when they are registered as an OSGi - * service. + * JettyServerServiceTracker + * + * Tracks instances of Jetty Servers, and configures them so that they can deploy + * webapps or ContextHandlers discovered from the OSGi environment. + * */ public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry { diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java index 6bd352da2ae..83dc00d265b 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/JettyContextHandlerServiceTracker.java @@ -18,28 +18,18 @@ package org.eclipse.jetty.osgi.boot.internal.webapp; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.eclipse.jetty.osgi.boot.BundleWebAppProvider; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.osgi.boot.OSGiWebappConstants; import org.eclipse.jetty.osgi.boot.ServiceProvider; -import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper; -import org.eclipse.jetty.osgi.boot.internal.serverfactory.IManagedJettyServerRegistry; -import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.Scanner; -import org.eclipse.jetty.webapp.WebAppContext; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; @@ -195,6 +185,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener try { added = e.getValue().serviceAdded(sr, contextHandler); + System.err.println(serverName+" deployed "+contextHandler+": "+added); if (added && LOG.isDebugEnabled()) LOG.debug("Provider "+e.getValue()+" deployed "+contextHandler); } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java index c66fa26b12a..705c9cfa722 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java @@ -33,6 +33,9 @@ import java.util.Set; import org.eclipse.jetty.server.Server; /** + * LibExtClassLoaderHelper + * + * * Helper to create a URL class-loader with the jars inside * ${jetty.home}/lib/ext and ${jetty.home}/resources. In an ideal world, every * library is an OSGi bundle that does loads nicely. To support standard jars or @@ -40,41 +43,18 @@ import org.eclipse.jetty.server.Server; * inserting the jars in the usual jetty/lib/ext folders in the proper classpath * for the webapps. *

    - * Also the folder resources typically contains central configuration files for - * things like: log config and others. We enable fragments to register classes - * that are called back and passed those resources to do what they need to do. + * The drawback is that those jars will not be available in the OSGi + * classloader. *

    *

    - * For example the test-jndi webapplication depends on derby, derbytools, - * atomikos none of them are osgi bundles. we can either re-package them or we - * can place them in the usual lib/ext.
    - * In fact jasper's jsp libraries should maybe place in lib/ext too. - *

    - *

    - * The drawback is that those libraries will not be available in the OSGi - * classloader. Note that we could have setup those jars as embedded jars of the - * current bundle. However, we would need to know in advance what are those jars - * which was not acceptable. Also having those jars in a URLClassLoader seem to - * be required for some cases. For example jaspers' TldLocationsCache (replaced - * by TldScanner for servlet-3.0).
    - * Also all the dependencies of those libraries must be resolvable directly from - * the JettyBootstrapActivator bundle as it is set as the parent classloader. For - * example: if atomikos is placed in lib/ext it will work if and only if - * JettyBootstrapActivator import the necessary packages from javax.naming*, - * javax.transaction*, javax.mail* etc Most of the common cases of javax are - * added as optional import packages into jetty bootstrapper plugin. When there - * are not covered: please make a request or create a fragment or register a - * bundle with a buddy-policy onto the jetty bootstrapper.. - *

    - *

    - * Alternatives to placing jars in lib/ext + * Alternatives to placing jars in lib/ext: *

      - *
    1. Bundle the jars in an osgi bundle. Have the webapp(s) that context - * depends on them depend on that bundle. Things will go well for jetty.
    2. + *
    3. Bundle the jars in an osgi bundle. Have the webapp(s) that need these jars + * depend on that bundle.
    4. *
    5. Bundle those jars in an osgi bundle-fragment that targets the * jetty-bootstrap bundle
    6. *
    7. Use equinox Buddy-Policy: register a buddy of the jetty bootstrapper - * bundle. (least favorite: it will work only on equinox)
    8. + * bundle. (Note: it will work only on equinox) *
    *

    */ diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java index 5f7e6443d95..71e9e7936fc 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java @@ -33,7 +33,6 @@ import java.util.jar.JarFile; import javax.servlet.http.HttpServlet; -import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper; import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelperFactory; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -44,8 +43,10 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleReference; /** - * Extends the webappclassloader to insert the classloader provided by the osgi - * bundle at the same level than any other jars palced in the webappclassloader. + * OSGiWebappClassLoader + * + * + * Extends the webapp classloader to also use the classloader of the Bundle defining the webapp. */ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleReference { @@ -79,10 +80,9 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe private boolean _lookInOsgiFirst = true; - private Set _libsAlreadyInManifest = new HashSet(); /** - * @param parent The parent classloader. In this case + * @param parent The parent classloader. * @param context The WebAppContext * @param contributor The bundle that defines this web-application. * @throws IOException @@ -106,16 +106,6 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe return _contributor; } - /** - * Reads the manifest. If the manifest is already configured to loads a few - * libs we should not add them to the classpath of the webapp. Not really - * important as we resolve classes through the osgi classloader first and - * then default on the libs of the webapp. - */ - private void computeLibsAlreadyInOSGiClassLoader() - { - // TODO - } @Override public Enumeration getResources(String name) throws IOException diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java index b8adc657054..5181b33b51c 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebBundleTrackerCustomizer.java @@ -21,6 +21,10 @@ package org.eclipse.jetty.osgi.boot.internal.webapp; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; import org.eclipse.jetty.osgi.boot.BundleProvider; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; @@ -39,12 +43,9 @@ import org.osgi.util.tracker.ServiceTracker; * WebBundleTrackerCustomizer * * - * Support bundles that declare a webpp or context directly through headers in their - * manifest. They will be deployed to the default jetty Server instance. - * - * If you wish to deploy a context or webapp to a different jetty Server instance, - * register your context/webapp as an osgi service, and set the property OSGiServerConstants.MANAGED_JETTY_SERVER_NAME - * with the name of the Server instance you wish to depoy to. + * Tracks the installation and removal of Bundles in the OSGi environment. Any bundles + * that are added are passed to the set of Jetty DeploymentManager providers to see if + * the bundle should be deployed as a webapp or ContextHandler into Jetty. * * @author hmalphettes */ @@ -53,35 +54,109 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer private static final Logger LOG = Log.getLogger(WebBundleTrackerCustomizer.class); public static Collection JSP_REGISTRATION_HELPERS = new ArrayList(); - public static final String FILTER = "(&(objectclass=" + BundleProvider.class.getName() + ")"+ - "("+OSGiServerConstants.MANAGED_JETTY_SERVER_NAME+"="+OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME+"))"; + + public static final String FILTER = "(objectclass=" + BundleProvider.class.getName() + ")"; private ServiceTracker _serviceTracker; private BundleTracker _bundleTracker; + private boolean _waitForDefaultServer = true; + private boolean _defaultServerReady = false; + private Bundle _bundle = null; + + /* ------------------------------------------------------------ */ /** * @throws Exception */ - public WebBundleTrackerCustomizer () - throws Exception + public WebBundleTrackerCustomizer() throws Exception { - Bundle myBundle = FrameworkUtil.getBundle(this.getClass()); - - //track all instances of deployers of webapps/contexts as bundles - _serviceTracker = new ServiceTracker(myBundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null) { - public Object addingService(ServiceReference reference) { - Object object = super.addingService(reference); - LOG.debug("Deployer registered {}", reference); - openBundleTracker(); - return object; - } - }; + _bundle = FrameworkUtil.getBundle(this.getClass()); + //Track all BundleProviders (Jetty DeploymentManager Providers that can deploy bundles) + _serviceTracker = new ServiceTracker(_bundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null); _serviceTracker.open(); - } + + public boolean isWaitForDefaultServer() + { + return _waitForDefaultServer; + } + + + + public void setWaitForDefaultServer(boolean waitForDefaultServer) + { + _waitForDefaultServer = waitForDefaultServer; + } + + public void setBundleTracker (BundleTracker bundleTracker) + { + _bundleTracker = bundleTracker; + } + + public void open () throws Exception + { + if (_waitForDefaultServer && !_defaultServerReady) + { + String filter = "(&(objectclass=" + BundleProvider.class.getName() + ")"+ + "("+OSGiServerConstants.MANAGED_JETTY_SERVER_NAME+"="+OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME+"))"; + + ServiceTracker defaultServerTracker = new ServiceTracker(_bundle.getBundleContext(), + FrameworkUtil.createFilter(filter),null) + { + public Object addingService(ServiceReference reference) + { + try + { + Object object = super.addingService(reference); + LOG.debug("Default Jetty Server registered {}", reference); + _defaultServerReady = true; + openBundleTracker(); + return object; + } + catch (Exception e) + { + throw new IllegalStateException(e); + } + } + }; + defaultServerTracker.open(); + } + else + openBundleTracker(); + } + + /* ------------------------------------------------------------ */ + /** + * @param managedServerName + * @return + */ + public Map getDeployers(String managedServerName) + { + if (managedServerName == null) + managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME; + + Map candidates = new HashMap(); + + ServiceReference[] references = _serviceTracker.getServiceReferences(); + if (references != null) + { + for (ServiceReference ref:references) + { + String name = (String)ref.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + if (managedServerName.equalsIgnoreCase(name)) + { + BundleProvider candidate = (BundleProvider)_serviceTracker.getService(ref); + if (candidate != null) + candidates.put(ref, candidate); + } + } + } + return candidates; + } + /* ------------------------------------------------------------ */ /** * A bundle is being added to the BundleTracker. @@ -138,8 +213,6 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer */ public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) { - // nothing the web-bundle was already track. something changed. - // we only reload the webapps if the bundle is stopped and restarted. if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE) { unregister(bundle); @@ -171,35 +244,40 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer } + protected void openBundleTracker() + { + _bundleTracker.open(); + } + /* ------------------------------------------------------------ */ /** * @param bundle - * @return true if this bundle in indeed a web-bundle. + * @return true if this bundle can be deployed into Jetty */ private boolean register(Bundle bundle) { if (bundle == null) return false; - //It might be a bundle that we can deploy to our default jetty server instance + //It might be a bundle that is deployable by Jetty. + //Use any named Server instance provided, defaulting to the default Server instance if none supplied boolean deployed = false; - Object[] deployers = _serviceTracker.getServices(); - if (deployers != null) + String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + Map candidates = getDeployers(serverName); + if (candidates != null) { - int i=0; - while (!deployed && i> itor = candidates.entrySet().iterator(); + while (!deployed && itor.hasNext()) { - - BundleProvider p = (BundleProvider)deployers[i]; + Entry e = itor.next(); try - { - deployed = p.bundleAdded(bundle); + { + deployed = e.getValue().bundleAdded(bundle); } catch (Exception x) { LOG.warn("Error deploying bundle for jetty context", x); } - i++; } } @@ -212,39 +290,24 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer */ private void unregister(Bundle bundle) { - Object[] deployers = _serviceTracker.getServices(); boolean undeployed = false; - if (deployers != null) + String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + Map candidates = getDeployers(serverName); + if (candidates != null) { - int i=0; - while (!undeployed && i> itor = candidates.entrySet().iterator(); + while (!undeployed && itor.hasNext()) { + Entry e = itor.next(); try { - undeployed = ((BundleProvider)deployers[i++]).bundleRemoved(bundle); + undeployed = e.getValue().bundleRemoved(bundle); } catch (Exception x) { - LOG.warn("Error undeploying bundle for jetty context", x); + LOG.warn("Error undeploying Bundle representing jetty deployable ", x); } } } } - - public void setAndOpenWebBundleTracker(BundleTracker bundleTracker) { - if(_bundleTracker == null) { - _bundleTracker = bundleTracker; - LOG.debug("Bundle tracker is set"); - openBundleTracker(); - } - } - - private void openBundleTracker() { - if(_bundleTracker != null && _serviceTracker.getServices() != null && - _serviceTracker.getServices().length > 0) { - _bundleTracker.open(); - LOG.debug("Bundle tracker has been opened"); - } - } - } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java index 8850f5e6397..91f42afb941 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/OSGiClassLoader.java @@ -78,8 +78,7 @@ public class OSGiClassLoader extends URLClassLoader } if (url == null) - { - + { url = _osgiBundleClassLoader.getResource(name); if (url == null && name.startsWith("/")) diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java index 813bff42fcb..736fcb254ff 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/WebappRegistrationCustomizer.java @@ -24,7 +24,9 @@ import org.eclipse.jetty.deploy.DeploymentManager; /** - * Fix various shortcomings with the way jasper parses the tld files. + * WebappRegistrationCustomizer + * + * Convert bundles that contain tlds into URL locations for consumption by jasper. */ public interface WebappRegistrationCustomizer { @@ -35,25 +37,13 @@ public interface WebappRegistrationCustomizer */ public static final String CLASS_NAME = "org.eclipse.jetty.osgi.boot.jasper.WebappRegistrationCustomizerImpl"; + /** - * TODO: right now only the jetty-jsp bundle is scanned for common taglibs. - * Should support a way to plug more bundles that contain taglibs. + * Find bundles that contain tlds and convert into URL references to their location. * - * The jasper TldScanner expects a URLClassloader to parse a jar for the - * /META-INF/*.tld it may contain. We place the bundles that we know contain - * such tag-libraries. Please note that it will work if and only if the - * bundle is a jar (!) Currently we just hardcode the bundle that contains - * the jstl implemenation. - * - * A workaround when the tld cannot be parsed with this method is to copy - * and paste it inside the WEB-INF of the webapplication where it is used. - * - * Support only 2 types of packaging for the bundle: - the bundle is a jar - * (recommended for runtime.) - the bundle is a folder and contain jars in - * the root and/or in the lib folder (nice for PDE developement situations) - * Unsupported: the bundle is a jar that embeds more jars. - * - * @return array of URLs + * @param manager + * @param fileLocator + * @return array of URLs representing locations of tld containing bundles * @throws Exception */ URL[] getJarsWithTlds(DeploymentManager manager, BundleFileLocatorHelper fileLocator) throws Exception; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java index 9bb074a5f22..ee0d7c225ed 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java @@ -28,6 +28,9 @@ import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; /** + * DefaultBundleClassLoaderHelper + * + * * Default implementation of the BundleClassLoaderHelper. Uses introspection to * support equinox-3.5 and felix-2.0.0 */ diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java index 2d31459de17..eb23d5924bf 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java @@ -36,6 +36,9 @@ import org.eclipse.jetty.util.resource.FileResource; import org.osgi.framework.Bundle; /** + * DefaultFileLocatorHelper + * + * * From a bundle to its location on the filesystem. Assumes the bundle is not a * jar. * diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java index 384b392c9ae..c3fd3aa5912 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/PackageAdminServiceTracker.java @@ -35,6 +35,9 @@ import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.startlevel.StartLevel; /** + * PackageAdminServiceTracker + * + * * When the PackageAdmin service is activated we can look for the fragments * attached to this bundle and "activate" them. */