org.eclipse.jetty.osgi.JettyBootstrapActivator Maven / Gradle / Ivy
Show all versions of jetty-osgi Show documentation
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.osgi;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory;
import org.eclipse.jetty.osgi.util.OSGiClassLoader;
import org.eclipse.jetty.osgi.util.Util;
import org.eclipse.jetty.server.Server;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JettyBootstrapActivator
*
* Bootstrap jetty and publish a default Server instance as an OSGi service.
*/
public class JettyBootstrapActivator implements BundleActivator
{
private static final Logger LOG = LoggerFactory.getLogger(JettyBootstrapActivator.class);
private static JettyBootstrapActivator INSTANCE = null;
/**
* contains a comma separated list of paths to the etc/jetty-*.xml files
*/
public static final String JETTY_ETC_FILES = OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS;
/**
* Set of config files to apply to a jetty Server instance if none are supplied by SYS_PROP_JETTY_ETC_FILES
*/
public static final String DEFAULT_JETTY_ETC_FILES = "etc/jetty.xml,etc/jetty-http.xml,etc/jetty-deploy.xml";
/**
* Default location within bundle of a jetty home dir.
*/
public static final String DEFAULT_JETTYHOME = "/jettyhome";
private ServiceRegistration> _registeredServer;
/* private PackageAdminServiceTracker _packageAdminServiceTracker;*/
/**
* Setup a new jetty Server, register it as a service.
*
* @param context the bundle context
*/
@Override
public void start(final BundleContext context) throws Exception
{
// track other bundles and fragments attached to this bundle that we
// should activate, as OSGi will not call activators for them.
/* _packageAdminServiceTracker = new PackageAdminServiceTracker(context);*/
ServiceReference[] references = context.getAllServiceReferences("org.eclipse.jetty.http.HttpFieldPreEncoder", null);
if (references == null || references.length == 0)
LOG.warn("OSGi support for java.util.ServiceLoader may not be present. You may experience runtime errors.");
// Create a default jetty instance right now.
startJettyAtJettyHome(context);
}
/**
* Stop the activator.
*
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) throws Exception
{
/* if (_packageAdminServiceTracker != null)
{
_packageAdminServiceTracker.stop();
context.removeServiceListener(_packageAdminServiceTracker);
_packageAdminServiceTracker = null;
}
*/
try
{
if (_registeredServer != null)
{
try
{
_registeredServer.unregister();
}
catch (IllegalArgumentException ill)
{
// already unregistered.
}
finally
{
_registeredServer = null;
}
}
}
finally
{
INSTANCE = null;
}
}
/**
* If the system property jetty.home is defined and points to a folder,
* creates a corresponding jetty server.
*
* If the system property jetty.home.bundle is defined and points to a
* bundle, look for the configuration of jetty inside that bundle.
*
*
* In both cases reads the system property 'jetty.etc.config.urls' to locate
* the configuration files for the deployed jetty. It is a comma separated
* list of URLs or relative paths inside the bundle or folder to the config
* files.
*
*
* In both cases the system properties jetty.http.host, jetty.http.port and
* jetty.ssl.port are passed to the configuration files that might use them
* as part of their properties.
*
*
* @param bundleContext the bundle context
* @throws Exception if unable to create / configure / or start the server
*/
private void startJettyAtJettyHome(BundleContext bundleContext) throws Exception
{
String jettyHomeSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME);
String jettyHomeBundleSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME_BUNDLE);
File jettyHomeDir = null;
Bundle jettyHomeBundle = null;
Dictionary properties = new Hashtable<>();
if (jettyHomeSysProp != null)
{
jettyHomeSysProp = Util.resolvePropertyValue(jettyHomeSysProp);
// bug 329621
if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'")))
jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1);
if (jettyHomeBundleSysProp != null)
LOG.warn("Both jetty.home and jetty.home.bundle property defined: jetty.home.bundle ignored.");
jettyHomeDir = new File(jettyHomeSysProp);
if (!jettyHomeDir.exists() || !jettyHomeDir.isDirectory())
{
LOG.warn("Unable to locate the jetty.home folder {}", jettyHomeSysProp);
return;
}
//set jetty.home
Util.setProperty(properties, OSGiServerConstants.JETTY_HOME, jettyHomeDir.getAbsolutePath());
}
else if (jettyHomeBundleSysProp != null)
{
jettyHomeBundleSysProp = Util.resolvePropertyValue(jettyHomeBundleSysProp);
for (Bundle b : bundleContext.getBundles())
{
if (b.getState() == Bundle.UNINSTALLED)
continue;
if (b.getSymbolicName().equals(jettyHomeBundleSysProp))
{
jettyHomeBundle = b;
break;
}
}
if (jettyHomeBundle == null)
{
LOG.warn("Unable to find the jetty.home.bundle named {}", jettyHomeSysProp);
return;
}
}
if (jettyHomeDir == null && jettyHomeBundle == null)
{
LOG.warn("No default jetty created.");
return;
}
//resolve the jetty xml config files
List configURLs = jettyHomeDir != null ? getJettyConfigurationURLs(jettyHomeDir) : getJettyConfigurationURLs(jettyHomeBundle, properties);
LOG.info("Configuring the default jetty server with {}", configURLs);
String home = (String)properties.get(OSGiServerConstants.JETTY_HOME);
String base = (String)properties.get(OSGiServerConstants.JETTY_BASE);
if (base == null)
base = home;
LOG.info("JETTY.HOME={} JETTY.BASE={}", home, base);
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
try
{
ClassLoader cl;
if (jettyHomeBundle != null)
{
cl = new OSGiClassLoader(JettyBootstrapActivator.class.getClassLoader(), jettyHomeBundle);
}
else
{
cl = JettyBootstrapActivator.class.getClassLoader();
}
Thread.currentThread().setContextClassLoader(cl);
//the default server name
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME);
//Always set home and base
Util.setProperty(properties, OSGiServerConstants.JETTY_HOME, home);
Util.setProperty(properties, OSGiServerConstants.JETTY_BASE, base);
// copy all system properties starting with "jetty." to service properties for the jetty server service.
// these will be used as xml configuration properties.
for (Map.Entry