Starting an embedded Jetty 7 server in Equinox is easy, but getting the right configuration in the right place can be slightly harder.
I am currently using the following Jetty bundles:
org.eclipse.jetty.client
org.eclipse.jetty.continuation
org.eclipse.jetty.deploy
org.eclipse.jetty.http
org.eclipse.jetty.io
org.eclipse.jetty.jmx
org.eclipse.jetty.osgi.boot
org.eclipse.jetty.security
org.eclipse.jetty.server
org.eclipse.jetty.servlet
org.eclipse.jetty.servlets
org.eclipse.jetty.util
org.eclipse.jetty.webapp
org.eclipse.jetty.xml
Some bundles are required only because I want to support gzip loading, jmx introspection and authentication. What bundles can be removed is left as an exercise to the reader.
Jetty is started by the org.eclipse.jetty.osgi.boot
bundle, so I make sure this is auto-started. However, in order for Jetty to become useful I also need to reconfigure it.
When the Jetty boot bundle is activated, it runs the DefaultJettyAtJettyHomeHelper#startJettyAtJettyHome(org.osgi.framework.BundleContext) method and that in turn looks at a few properties to determine where to read the configuration from. We elected to use the jetty.home.bundle
property.
Armed with the information gleaned from those docs, and the instructions on how to inject new server-wide features into Jetty-OSGi on the eclipse wiki, I created a fragment bundle that is loaded and activated with org.eclipse.jetty.osgi.boot
and modifies the jetty.home.bundle
property so the configuration is read from the fragment bundle instead of the one included in the Jetty boot bundle.
To set the property I created a fragment activator (all package names have been changed to protect the innocent):
package jettyconfig;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class FragmentActivator implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
// Set jetty.home.bundle to the name of our bundle
System.setProperty("jetty.home.bundle", "jettyconfig");
}
@Override
public void stop(BundleContext context) throws Exception {
}
}
The fragment activator will be executed just before the Jetty boot bundle is activated.
It would also be possible to set this property from the command-line (as is probably more proper), but after some discussion we preferred to do it like this until something better comes along.
The MANIFEST.MF looks like this:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Jetty Configuration
Bundle-SymbolicName: jettyconfig
Bundle-Version: 1.0.0.qualifier
Fragment-Host: org.eclipse.jetty.osgi.boot;bundle-version="7.2.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Vendor: Henrik Gustafsson
Finally, I could put my config in /etc/jetty.xml in the fragment bundle, and Jetty is started with this configuration. As a starting point for my jetty.xml I used the jetty-osgi-default.xml file and the notes on the jetty.xml wiki page. In particular I needed a ContextHandlerCollection
(or perhaps a OSGiAppProvider) configured for Jetty to pick up the services properly.