public void configureContextHandler() throws Exception { if (_configured) return; _configured = true; // Override for bundle root may have been set String bundleOverrideLocation = (String) _properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); if (bundleOverrideLocation == null) bundleOverrideLocation = (String) _properties.get(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE); // Location on filesystem of bundle or the bundle override location File bundleLocation = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle); File root = (bundleOverrideLocation == null ? bundleLocation : new File(bundleOverrideLocation)); Resource rootResource = Resource.newResource( BundleFileLocatorHelperFactory.getFactory() .getHelper() .getLocalURL(root.toURI().toURL())); // try and make sure the rootResource is useable - if its a jar then make it a jar file url if (rootResource.exists() && !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:")) { Resource jarResource = JarResource.newJarResource(rootResource); if (jarResource.exists() && jarResource.isDirectory()) rootResource = jarResource; } // Set the base resource of the ContextHandler, if not already set, can also be overridden by // the context xml file if (_contextHandler != null && _contextHandler.getBaseResource() == null) { _contextHandler.setBaseResource(rootResource); } // Use a classloader that knows about the common jetty parent loader, and also the bundle OSGiClassLoader classLoader = new OSGiClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps(), _bundle); // if there is a context file, find it and apply it if (_contextFile == null && _contextHandler == null) throw new IllegalStateException("No context file or ContextHandler"); if (_contextFile != null) { // apply the contextFile, creating the ContextHandler, the DeploymentManager will register // it in the ContextHandlerCollection Resource res = null; // try to find the context file in the filesystem if (_contextFile.startsWith("/")) res = getFileAsResource(_contextFile); // try to find it relative to jetty home if (res == null) { // See if the specific server we are related to has jetty.home set String jettyHome = (String) getServerInstanceWrapper() .getServer() .getAttribute(OSGiServerConstants.JETTY_HOME); if (jettyHome != null) res = getFileAsResource(jettyHome, _contextFile); // try to see if a SystemProperty for jetty.home is set if (res == null) { jettyHome = System.getProperty(OSGiServerConstants.JETTY_HOME); if (jettyHome != null) { if (jettyHome.startsWith("\"") || jettyHome.startsWith("'")) jettyHome = jettyHome.substring(1); if (jettyHome.endsWith("\"") || (jettyHome.endsWith("'"))) jettyHome = jettyHome.substring(0, jettyHome.length() - 1); res = getFileAsResource(jettyHome, _contextFile); if (LOG.isDebugEnabled()) LOG.debug("jetty home context file:" + res); } } } // try to find it relative to an override location that has been specified if (res == null) { if (bundleOverrideLocation != null) { res = getFileAsResource( Resource.newResource(bundleOverrideLocation).getFile(), _contextFile); if (LOG.isDebugEnabled()) LOG.debug("Bundle override location context file:" + res); } } // try to find it relative to the bundle in which it is being deployed if (res == null) { if (_contextFile.startsWith("./")) _contextFile = _contextFile.substring(1); if (!_contextFile.startsWith("/")) _contextFile = "/" + _contextFile; URL contextURL = _bundle.getEntry(_contextFile); if (contextURL != null) res = Resource.newResource(contextURL); } // apply the context xml file, either to an existing ContextHandler, or letting the // it create the ContextHandler as necessary if (res != null) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); LOG.debug("Context classloader = " + cl); try { Thread.currentThread().setContextClassLoader(classLoader); XmlConfiguration xmlConfiguration = new XmlConfiguration(res.getInputStream()); HashMap properties = new HashMap(); // put the server instance in properties.put("Server", getServerInstanceWrapper().getServer()); // put in the location of the bundle root properties.put("bundle.root", rootResource.toString()); // insert the bundle's location as a property. xmlConfiguration.getProperties().putAll(properties); if (_contextHandler == null) _contextHandler = (ContextHandler) xmlConfiguration.configure(); else xmlConfiguration.configure(_contextHandler); } finally { Thread.currentThread().setContextClassLoader(cl); } } } // Set up the class loader we created _contextHandler.setClassLoader(classLoader); // If a bundle/service property specifies context path, let it override the context xml String contextPath = (String) _properties.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); if (contextPath == null) contextPath = (String) _properties.get(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH); if (contextPath != null) _contextHandler.setContextPath(contextPath); // osgi Enterprise Spec r4 p.427 _contextHandler.setAttribute( OSGiWebappConstants.OSGI_BUNDLECONTEXT, _bundle.getBundleContext()); // make sure we protect also the osgi dirs specified by OSGi Enterprise spec String[] targets = _contextHandler.getProtectedTargets(); int length = (targets == null ? 0 : targets.length); String[] updatedTargets = null; if (targets != null) { updatedTargets = new String[length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; System.arraycopy(targets, 0, updatedTargets, 0, length); } else updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; System.arraycopy( OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); _contextHandler.setProtectedTargets(updatedTargets); }