375096 If starting a server instance fails in osgi it is cleaned up.
This commit is contained in:
parent
241997b449
commit
72951403d3
|
@ -39,7 +39,7 @@ import org.osgi.framework.BundleContext;
|
|||
public class DefaultJettyAtJettyHomeHelper {
|
||||
private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* contains a comma separated list of pathes to the etc/jetty-*.xml files
|
||||
* used to configure jetty. By default the value is 'etc/jetty.xml' when the
|
||||
|
@ -69,7 +69,7 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
* Usual system property used as the port for https for a typical jetty configuration.
|
||||
*/
|
||||
public static final String SYS_PROP_JETTY_PORT_SSL = "jetty.port.ssl";
|
||||
|
||||
|
||||
/**
|
||||
* Called by the JettyBootStrapActivator.
|
||||
* If the system property jetty.home is defined and points to a folder,
|
||||
|
@ -88,81 +88,76 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
* that might use them as part of their properties.
|
||||
* </p>
|
||||
*/
|
||||
public static void startJettyAtJettyHome(BundleContext bundleContext)
|
||||
public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME);
|
||||
String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE);
|
||||
File jettyHome = null;
|
||||
Bundle jettyHomeBundle = null;
|
||||
if (jettyHomeSysProp != null)
|
||||
{
|
||||
jettyHomeSysProp = 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 the jetty.home property and the jetty.home.bundle property are defined."
|
||||
+ " jetty.home.bundle is not taken into account.");
|
||||
}
|
||||
jettyHome = new File(jettyHomeSysProp);
|
||||
if (!jettyHome.exists() || !jettyHome.isDirectory())
|
||||
{
|
||||
LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp);
|
||||
for (Bundle b : bundleContext.getBundles())
|
||||
{
|
||||
if (b.getSymbolicName().equals(jettyHomeBundleSysProp))
|
||||
{
|
||||
jettyHomeBundle = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
if (jettyHome == null && jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("No default jetty started.");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Server server = new Server();
|
||||
Dictionary properties = new Hashtable();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME);
|
||||
|
||||
String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle);
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs);
|
||||
String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME);
|
||||
String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE);
|
||||
File jettyHome = null;
|
||||
Bundle jettyHomeBundle = null;
|
||||
if (jettyHomeSysProp != null)
|
||||
{
|
||||
jettyHomeSysProp = 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 the jetty.home property and the jetty.home.bundle property are defined."
|
||||
+ " jetty.home.bundle is not taken into account.");
|
||||
}
|
||||
jettyHome = new File(jettyHomeSysProp);
|
||||
if (!jettyHome.exists() || !jettyHome.isDirectory())
|
||||
{
|
||||
LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp);
|
||||
for (Bundle b : bundleContext.getBundles())
|
||||
{
|
||||
if (b.getSymbolicName().equals(jettyHomeBundleSysProp))
|
||||
{
|
||||
jettyHomeBundle = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("Configuring the default jetty server with " + configURLs);
|
||||
|
||||
//these properties usually are the ones passed to this type of configuration.
|
||||
setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME));
|
||||
setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL));
|
||||
}
|
||||
if (jettyHome == null && jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("No default jetty started.");
|
||||
return;
|
||||
}
|
||||
|
||||
Server server = new Server();
|
||||
Dictionary properties = new Hashtable();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME);
|
||||
|
||||
String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle);
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs);
|
||||
|
||||
LOG.info("Configuring the default jetty server with " + configURLs);
|
||||
|
||||
//these properties usually are the ones passed to this type of configuration.
|
||||
setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME));
|
||||
setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL));
|
||||
|
||||
bundleContext.registerService(Server.class.getName(), server, properties);
|
||||
// hookNestedConnectorToBridgeServlet(server);
|
||||
|
||||
bundleContext.registerService(Server.class.getName(), server, properties);
|
||||
// hookNestedConnectorToBridgeServlet(server);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Minimum setup for the location of the configuration files given a jettyhome folder.
|
||||
* Reads the system property jetty.etc.config.urls and look for the corresponding jetty
|
||||
|
@ -172,22 +167,22 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
*/
|
||||
private static String getJettyConfigurationURLs(File jettyhome)
|
||||
{
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false);
|
||||
StringBuilder res = new StringBuilder();
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String next = tokenizer.nextToken().trim();
|
||||
if (!next.startsWith("/") && next.indexOf(':') == -1)
|
||||
{
|
||||
try {
|
||||
next = new File(jettyhome, next).toURI().toURL().toString();
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
appendToCommaSeparatedList(res, next);
|
||||
String next = tokenizer.nextToken().trim();
|
||||
if (!next.startsWith("/") && next.indexOf(':') == -1)
|
||||
{
|
||||
try {
|
||||
next = new File(jettyhome, next).toURI().toURL().toString();
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
appendToCommaSeparatedList(res, next);
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
@ -202,108 +197,108 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
*/
|
||||
private static String getJettyConfigurationURLs(Bundle configurationBundle)
|
||||
{
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false);
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String etcFile = tokenizer.nextToken().trim();
|
||||
if (etcFile.startsWith("/") || etcFile.indexOf(":") != -1)
|
||||
{
|
||||
appendToCommaSeparatedList(res, etcFile);
|
||||
appendToCommaSeparatedList(res, etcFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, etcFile);
|
||||
|
||||
//default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration.
|
||||
//default inside jettyhome. this way fragments to the bundle can define their own configuration.
|
||||
if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml"))
|
||||
{
|
||||
enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
|
||||
System.err.println("Configuring jetty with the default embedded configuration:" +
|
||||
"bundle: " + configurationBundle.getSymbolicName() +
|
||||
" config: /jettyhome/etc/jetty-osgi-default.xml");
|
||||
}
|
||||
if (enUrls == null || !enUrls.hasMoreElements())
|
||||
{
|
||||
System.err.println("Unable to locate a jetty configuration file for " + etcFile);
|
||||
}
|
||||
if (enUrls != null)
|
||||
{
|
||||
while (enUrls.hasMoreElements())
|
||||
{
|
||||
appendToCommaSeparatedList(res, enUrls.nextElement().toString());
|
||||
}
|
||||
}
|
||||
Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, etcFile);
|
||||
|
||||
//default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration.
|
||||
//default inside jettyhome. this way fragments to the bundle can define their own configuration.
|
||||
if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml"))
|
||||
{
|
||||
enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
|
||||
System.err.println("Configuring jetty with the default embedded configuration:" +
|
||||
"bundle: " + configurationBundle.getSymbolicName() +
|
||||
" config: /jettyhome/etc/jetty-osgi-default.xml");
|
||||
}
|
||||
if (enUrls == null || !enUrls.hasMoreElements())
|
||||
{
|
||||
System.err.println("Unable to locate a jetty configuration file for " + etcFile);
|
||||
}
|
||||
if (enUrls != null)
|
||||
{
|
||||
while (enUrls.hasMoreElements())
|
||||
{
|
||||
appendToCommaSeparatedList(res, enUrls.nextElement().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
private static void appendToCommaSeparatedList(StringBuilder buffer, String value)
|
||||
{
|
||||
if (buffer.length() != 0)
|
||||
{
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(value);
|
||||
}
|
||||
|
||||
private static void setProperty(Dictionary properties, String key, String value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
properties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively substitute the ${sysprop} by their actual system property.
|
||||
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined.
|
||||
* Not the most efficient code but we are shooting for simplicity and speed of development here.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String resolvePropertyValue(String value)
|
||||
{
|
||||
int ind = value.indexOf("${");
|
||||
if (ind == -1) {
|
||||
return value;
|
||||
}
|
||||
int ind2 = value.indexOf('}', ind);
|
||||
if (ind2 == -1) {
|
||||
return value;
|
||||
}
|
||||
String sysprop = value.substring(ind+2, ind2);
|
||||
String defaultValue = null;
|
||||
int comma = sysprop.indexOf(',');
|
||||
if (comma != -1 && comma+1 != sysprop.length())
|
||||
{
|
||||
defaultValue = sysprop.substring(comma+1);
|
||||
defaultValue = resolvePropertyValue(defaultValue);
|
||||
sysprop = sysprop.substring(0,comma);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue = "${" + sysprop + "}";
|
||||
}
|
||||
|
||||
String v = System.getProperty(sysprop);
|
||||
|
||||
String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : "";
|
||||
reminder = resolvePropertyValue(reminder);
|
||||
if (v != null)
|
||||
{
|
||||
return value.substring(0, ind) + v + reminder;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.substring(0, ind) + defaultValue + reminder;
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendToCommaSeparatedList(StringBuilder buffer, String value)
|
||||
{
|
||||
if (buffer.length() != 0)
|
||||
{
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(value);
|
||||
}
|
||||
|
||||
private static void setProperty(Dictionary properties, String key, String value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
properties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively substitute the ${sysprop} by their actual system property.
|
||||
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined.
|
||||
* Not the most efficient code but we are shooting for simplicity and speed of development here.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String resolvePropertyValue(String value)
|
||||
{
|
||||
int ind = value.indexOf("${");
|
||||
if (ind == -1) {
|
||||
return value;
|
||||
}
|
||||
int ind2 = value.indexOf('}', ind);
|
||||
if (ind2 == -1) {
|
||||
return value;
|
||||
}
|
||||
String sysprop = value.substring(ind+2, ind2);
|
||||
String defaultValue = null;
|
||||
int comma = sysprop.indexOf(',');
|
||||
if (comma != -1 && comma+1 != sysprop.length())
|
||||
{
|
||||
defaultValue = sysprop.substring(comma+1);
|
||||
defaultValue = resolvePropertyValue(defaultValue);
|
||||
sysprop = sysprop.substring(0,comma);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue = "${" + sysprop + "}";
|
||||
}
|
||||
|
||||
String v = System.getProperty(sysprop);
|
||||
|
||||
String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : "";
|
||||
reminder = resolvePropertyValue(reminder);
|
||||
if (v != null)
|
||||
{
|
||||
return value.substring(0, ind) + v + reminder;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.substring(0, ind) + defaultValue + reminder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,50 +18,53 @@ import java.util.Properties;
|
|||
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
/**
|
||||
* Deploy the jetty server instances when they are registered as an OSGi service.
|
||||
* Deploy the jetty server instances when they are registered as an OSGi
|
||||
* service.
|
||||
*/
|
||||
public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry
|
||||
{
|
||||
|
||||
private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName());
|
||||
|
||||
/**
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service.
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin
|
||||
* service.
|
||||
*/
|
||||
private Map<String, ServerInstanceWrapper> _serversIndexedByName = new HashMap<String, ServerInstanceWrapper>();
|
||||
|
||||
/** The context-handler to deactivate indexed by ServerInstanceWrapper */
|
||||
private Map<ServiceReference, ServerInstanceWrapper> _indexByServiceReference = new HashMap<ServiceReference, ServerInstanceWrapper>();
|
||||
|
||||
|
||||
/**
|
||||
* Stops each one of the registered servers.
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
//not sure that this is really useful but here we go.
|
||||
for (ServerInstanceWrapper wrapper : _serversIndexedByName.values())
|
||||
{
|
||||
try
|
||||
{
|
||||
wrapper.stop();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
// not sure that this is really useful but here we go.
|
||||
for (ServerInstanceWrapper wrapper : _serversIndexedByName.values())
|
||||
{
|
||||
try
|
||||
{
|
||||
wrapper.stop();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.warn(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receives notification that a service has had a lifecycle change.
|
||||
*
|
||||
* @param ev
|
||||
* The <code>ServiceEvent</code> object.
|
||||
* @param ev The <code>ServiceEvent</code> object.
|
||||
*/
|
||||
public void serviceChanged(ServiceEvent ev)
|
||||
{
|
||||
|
@ -71,17 +74,16 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
case ServiceEvent.MODIFIED:
|
||||
case ServiceEvent.UNREGISTERING:
|
||||
{
|
||||
ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
|
||||
ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
|
||||
if (instance != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
instance.stop();
|
||||
instance.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,32 +98,35 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
}
|
||||
case ServiceEvent.REGISTERED:
|
||||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
Server server = (Server)contributor.getBundleContext().getService(sr);
|
||||
ServerInstanceWrapper wrapper = registerInIndex(server, sr);
|
||||
Properties props = new Properties();
|
||||
for (String key : sr.getPropertyKeys())
|
||||
{
|
||||
Object value = sr.getProperty(key);
|
||||
props.put(key, value);
|
||||
}
|
||||
wrapper.start(server, props);
|
||||
break;
|
||||
try
|
||||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
Server server = (Server) contributor.getBundleContext().getService(sr);
|
||||
ServerInstanceWrapper wrapper = registerInIndex(server, sr);
|
||||
Properties props = new Properties();
|
||||
for (String key : sr.getPropertyKeys())
|
||||
{
|
||||
Object value = sr.getProperty(key);
|
||||
props.put(key, value);
|
||||
}
|
||||
wrapper.start(server, props);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr)
|
||||
{
|
||||
String name = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null)
|
||||
{
|
||||
throw new IllegalArgumentException("The property " +
|
||||
OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory");
|
||||
}
|
||||
String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); }
|
||||
ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
|
||||
_indexByServiceReference.put(sr,wrapper);
|
||||
_serversIndexedByName.put(name,wrapper);
|
||||
_indexByServiceReference.put(sr, wrapper);
|
||||
_serversIndexedByName.put(name, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
@ -133,7 +138,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
*/
|
||||
private ServerInstanceWrapper unregisterInIndex(ServiceReference sr)
|
||||
{
|
||||
ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
|
||||
ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
|
||||
if (handler == null)
|
||||
{
|
||||
// a warning?
|
||||
|
@ -149,13 +154,12 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
|
||||
/**
|
||||
* @param managedServerName The server name
|
||||
* @return the corresponding jetty server wrapped with its deployment properties.
|
||||
* @return the corresponding jetty server wrapped with its deployment
|
||||
* properties.
|
||||
*/
|
||||
public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
|
||||
{
|
||||
return _serversIndexedByName.get(managedServerName == null
|
||||
? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName);
|
||||
return _serversIndexedByName.get(managedServerName == null ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -99,14 +99,21 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null)
|
||||
{
|
||||
throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME,
|
||||
"The name of the server is mandatory");
|
||||
throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME,
|
||||
"The name of the server is mandatory");
|
||||
}
|
||||
serverInstanceWrapper = new ServerInstanceWrapper(name);
|
||||
_serversIndexedByPID.put(pid, serverInstanceWrapper);
|
||||
_serversNameIndexedByPID.put(pid, name);
|
||||
_serversPIDIndexedByName.put(name, pid);
|
||||
serverInstanceWrapper.start(new Server(), properties);
|
||||
try
|
||||
{
|
||||
serverInstanceWrapper.start(new Server(), properties);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ConfigurationException(null, "Error starting jetty server instance", e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void deleted(String pid)
|
||||
|
|
|
@ -44,28 +44,29 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
|
||||
/**
|
||||
* Exposes a Jetty Server to be managed by an OSGi ManagedServiceFactory
|
||||
* Configure and start it.
|
||||
* Can also be used from the ManagedServiceFactory
|
||||
* Configure and start it. Can also be used from the ManagedServiceFactory
|
||||
*/
|
||||
public class ServerInstanceWrapper {
|
||||
public class ServerInstanceWrapper
|
||||
{
|
||||
|
||||
/** The value of this property points to the parent director of
|
||||
* the jetty.xml configuration file currently executed.
|
||||
* Everything is passed as a URL to support the
|
||||
* case where the bundle is zipped. */
|
||||
/**
|
||||
* The value of this property points to the parent director of the jetty.xml
|
||||
* configuration file currently executed. Everything is passed as a URL to
|
||||
* support the case where the bundle is zipped.
|
||||
*/
|
||||
public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url";
|
||||
|
||||
private static Logger __logger = Log.getLogger(ServerInstanceWrapper.class.getName());
|
||||
|
||||
private static Logger LOG = Log.getLogger(ServerInstanceWrapper.class.getName());
|
||||
|
||||
private final String _managedServerName;
|
||||
|
||||
|
||||
/**
|
||||
* The managed jetty server
|
||||
*/
|
||||
private Server _server;
|
||||
|
||||
private ContextHandlerCollection _ctxtHandler;
|
||||
|
||||
/**
|
||||
|
@ -74,32 +75,34 @@ public class ServerInstanceWrapper {
|
|||
* let the TldScanner find the jars where the tld files are.
|
||||
*/
|
||||
private ClassLoader _commonParentClassLoaderForWebapps;
|
||||
|
||||
private DeploymentManager _deploymentManager;
|
||||
|
||||
private OSGiAppProvider _provider;
|
||||
|
||||
|
||||
private WebBundleDeployerHelper _webBundleDeployerHelper;
|
||||
|
||||
|
||||
|
||||
public ServerInstanceWrapper(String managedServerName)
|
||||
{
|
||||
_managedServerName = managedServerName;
|
||||
}
|
||||
|
||||
|
||||
public String getManagedServerName()
|
||||
{
|
||||
return _managedServerName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The classloader that should be the parent classloader for
|
||||
* each webapp deployed on this server.
|
||||
* The classloader that should be the parent classloader for each webapp
|
||||
* deployed on this server.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ClassLoader getParentClassLoaderForWebapps()
|
||||
{
|
||||
return _commonParentClassLoaderForWebapps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The deployment manager registered on this server.
|
||||
*/
|
||||
|
@ -107,7 +110,7 @@ public class ServerInstanceWrapper {
|
|||
{
|
||||
return _deploymentManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The app provider registered on this server.
|
||||
*/
|
||||
|
@ -115,19 +118,17 @@ public class ServerInstanceWrapper {
|
|||
{
|
||||
return _provider;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Server getServer()
|
||||
{
|
||||
return _server;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public WebBundleDeployerHelper getWebBundleDeployerHelp()
|
||||
{
|
||||
return _webBundleDeployerHelper;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The collection of context handlers
|
||||
*/
|
||||
|
@ -136,8 +137,7 @@ public class ServerInstanceWrapper {
|
|||
return _ctxtHandler;
|
||||
}
|
||||
|
||||
|
||||
public void start(Server server, Dictionary props)
|
||||
public void start(Server server, Dictionary props) throws Exception
|
||||
{
|
||||
_server = server;
|
||||
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
|
||||
|
@ -146,62 +146,61 @@ public class ServerInstanceWrapper {
|
|||
// passing this bundle's classloader as the context classlaoder
|
||||
// makes sure there is access to all the jetty's bundles
|
||||
ClassLoader libExtClassLoader = null;
|
||||
String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS);
|
||||
try
|
||||
{
|
||||
List<File> shared = sharedURLs != null ? extractFiles(sharedURLs) : null;
|
||||
libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(
|
||||
shared, null, server, JettyBootstrapActivator.class.getClassLoader());
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
String sharedURLs = (String) props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS);
|
||||
|
||||
List<File> shared = sharedURLs != null ? extractFiles(sharedURLs) : null;
|
||||
libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null, server, JettyBootstrapActivator.class.getClassLoader());
|
||||
|
||||
Thread.currentThread().setContextClassLoader(libExtClassLoader);
|
||||
|
||||
|
||||
configure(server, props);
|
||||
|
||||
init();
|
||||
|
||||
//now that we have an app provider we can call the registration customizer.
|
||||
try
|
||||
{
|
||||
URL[] jarsWithTlds = getJarsWithTlds();
|
||||
_commonParentClassLoaderForWebapps = jarsWithTlds == null
|
||||
? libExtClassLoader
|
||||
:new TldLocatableURLClassloader(libExtClassLoader,jarsWithTlds);
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
// now that we have an app provider we can call the registration
|
||||
// customizer.
|
||||
|
||||
URL[] jarsWithTlds = getJarsWithTlds();
|
||||
_commonParentClassLoaderForWebapps = jarsWithTlds == null ? libExtClassLoader : new TldLocatableURLClassloader(libExtClassLoader, jarsWithTlds);
|
||||
|
||||
|
||||
server.start();
|
||||
_webBundleDeployerHelper = new WebBundleDeployerHelper(this);
|
||||
}
|
||||
catch (Throwable t)
|
||||
catch (Exception e)
|
||||
{
|
||||
t.printStackTrace();
|
||||
if (server != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.ignore(x);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
_webBundleDeployerHelper = new WebBundleDeployerHelper(this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void stop()
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
if (_server.isRunning())
|
||||
{
|
||||
_server.stop();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,14 +228,13 @@ public class ServerInstanceWrapper {
|
|||
private URL[] getJarsWithTlds() throws Exception
|
||||
{
|
||||
ArrayList<URL> res = new ArrayList<URL>();
|
||||
WebBundleDeployerHelper.staticInit();//that is not looking great.
|
||||
WebBundleDeployerHelper.staticInit();// that is not looking great.
|
||||
for (WebappRegistrationCustomizer regCustomizer : WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS)
|
||||
{
|
||||
URL[] urls = regCustomizer.getJarsWithTlds(_provider, WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER);
|
||||
for (URL url : urls)
|
||||
{
|
||||
if (!res.contains(url))
|
||||
res.add(url);
|
||||
if (!res.contains(url)) res.add(url);
|
||||
}
|
||||
}
|
||||
if (!res.isEmpty())
|
||||
|
@ -244,19 +242,15 @@ public class ServerInstanceWrapper {
|
|||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void configure(Server server, Dictionary props) throws Exception
|
||||
{
|
||||
String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS);
|
||||
List<URL> jettyConfigurations = jettyConfigurationUrls != null
|
||||
? extractResources(jettyConfigurationUrls) : null;
|
||||
if (jettyConfigurations == null || jettyConfigurations.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Map<String,Object> id_map = new HashMap<String,Object>();
|
||||
id_map.put("Server",server);
|
||||
Map<String,String> properties = new HashMap<String,String>();
|
||||
List<URL> jettyConfigurations = jettyConfigurationUrls != null ? extractResources(jettyConfigurationUrls) : null;
|
||||
if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return; }
|
||||
Map<String, Object> id_map = new HashMap<String, Object>();
|
||||
id_map.put("Server", server);
|
||||
Map<String, String> properties = new HashMap<String, String>();
|
||||
Enumeration<Object> en = props.keys();
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
|
@ -275,15 +269,17 @@ public class ServerInstanceWrapper {
|
|||
is = r.getInputStream();
|
||||
XmlConfiguration config = new XmlConfiguration(is);
|
||||
config.getIdMap().putAll(id_map);
|
||||
|
||||
//#334062 compute the URL of the folder that contains the jetty.xml conf file
|
||||
//and set it as a property so we can compute relative paths from it.
|
||||
|
||||
// #334062 compute the URL of the folder that contains the
|
||||
// jetty.xml conf file
|
||||
// and set it as a property so we can compute relative paths
|
||||
// from it.
|
||||
String urlPath = jettyConfiguration.toString();
|
||||
int lastSlash = urlPath.lastIndexOf('/');
|
||||
if (lastSlash > 4)
|
||||
{
|
||||
urlPath = urlPath.substring(0, lastSlash);
|
||||
Map<String,String> properties2 = new HashMap<String,String>(properties);
|
||||
Map<String, String> properties2 = new HashMap<String, String>(properties);
|
||||
properties2.put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath);
|
||||
config.getProperties().putAll(properties2);
|
||||
}
|
||||
|
@ -292,11 +288,11 @@ public class ServerInstanceWrapper {
|
|||
config.getProperties().putAll(properties);
|
||||
}
|
||||
config.configure();
|
||||
id_map=config.getIdMap();
|
||||
id_map = config.getIdMap();
|
||||
}
|
||||
catch (SAXParseException saxparse)
|
||||
{
|
||||
__logger.warn("Unable to configure the jetty/etc file " + jettyConfiguration,saxparse);
|
||||
LOG.warn("Unable to configure the jetty/etc file " + jettyConfiguration, saxparse);
|
||||
throw saxparse;
|
||||
}
|
||||
finally
|
||||
|
@ -306,8 +302,7 @@ public class ServerInstanceWrapper {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Must be called after the server is configured.
|
||||
*
|
||||
|
@ -319,50 +314,48 @@ public class ServerInstanceWrapper {
|
|||
private void init()
|
||||
{
|
||||
// Get the context handler
|
||||
_ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class);
|
||||
|
||||
_ctxtHandler = (ContextHandlerCollection) _server.getChildHandlerByClass(ContextHandlerCollection.class);
|
||||
|
||||
// get a deployerManager
|
||||
List<DeploymentManager> deployers = _server.getBeans(DeploymentManager.class);
|
||||
if (deployers != null && !deployers.isEmpty())
|
||||
{
|
||||
_deploymentManager = deployers.get(0);
|
||||
|
||||
|
||||
for (AppProvider provider : _deploymentManager.getAppProviders())
|
||||
{
|
||||
if (provider instanceof OSGiAppProvider)
|
||||
{
|
||||
_provider=(OSGiAppProvider)provider;
|
||||
_provider = (OSGiAppProvider) provider;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_provider == null)
|
||||
{
|
||||
//create it on the fly with reasonable default values.
|
||||
// create it on the fly with reasonable default values.
|
||||
try
|
||||
{
|
||||
_provider = new OSGiAppProvider();
|
||||
_provider.setMonitoredDirResource(
|
||||
Resource.newResource(getDefaultOSGiContextsHome(
|
||||
new File(System.getProperty("jetty.home"))).toURI()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
_provider.setMonitoredDirResource(Resource.newResource(getDefaultOSGiContextsHome(new File(System.getProperty("jetty.home"))).toURI()));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
_deploymentManager.addAppProvider(_provider);
|
||||
}
|
||||
}
|
||||
|
||||
if (_ctxtHandler == null || _provider==null)
|
||||
throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured");
|
||||
|
||||
if (_ctxtHandler == null || _provider == null) throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The default folder in which the context files of the osgi bundles
|
||||
* are located and watched. Or null when the system property
|
||||
* "jetty.osgi.contexts.home" is not defined.
|
||||
* If the configuration file defines the OSGiAppProvider's context.
|
||||
* This will not be taken into account.
|
||||
* "jetty.osgi.contexts.home" is not defined. If the configuration
|
||||
* file defines the OSGiAppProvider's context. This will not be
|
||||
* taken into account.
|
||||
*/
|
||||
File getDefaultOSGiContextsHome(File jettyHome)
|
||||
{
|
||||
|
@ -370,20 +363,19 @@ public class ServerInstanceWrapper {
|
|||
if (jettyContextsHome != null)
|
||||
{
|
||||
File contextsHome = new File(jettyContextsHome);
|
||||
if (!contextsHome.exists() || !contextsHome.isDirectory())
|
||||
{
|
||||
throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder");
|
||||
}
|
||||
if (!contextsHome.exists() || !contextsHome.isDirectory()) { throw new IllegalArgumentException(
|
||||
"the ${jetty.osgi.contexts.home} '" + jettyContextsHome
|
||||
+ " must exist and be a folder"); }
|
||||
return contextsHome;
|
||||
}
|
||||
return new File(jettyHome, "/contexts");
|
||||
}
|
||||
|
||||
|
||||
File getOSGiContextsHome()
|
||||
{
|
||||
return _provider.getContextXmlDirAsFile();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the urls in this string.
|
||||
*/
|
||||
|
@ -396,19 +388,19 @@ public class ServerInstanceWrapper {
|
|||
String tok = tokenizer.nextToken();
|
||||
try
|
||||
{
|
||||
urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper
|
||||
.BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok)));
|
||||
urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok)));
|
||||
}
|
||||
catch (Throwable mfe)
|
||||
{
|
||||
|
||||
LOG.warn(mfe);
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the folders that might contain jars for the legacy J2EE shared libraries
|
||||
* Get the folders that might contain jars for the legacy J2EE shared
|
||||
* libraries
|
||||
*/
|
||||
private List<File> extractFiles(String propertyValue)
|
||||
{
|
||||
|
@ -420,8 +412,7 @@ public class ServerInstanceWrapper {
|
|||
try
|
||||
{
|
||||
URL url = new URL(tok);
|
||||
url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper
|
||||
.BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url);
|
||||
url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url);
|
||||
if (url.getProtocol().equals("file"))
|
||||
{
|
||||
Resource res = Resource.newResource(url);
|
||||
|
@ -434,11 +425,10 @@ public class ServerInstanceWrapper {
|
|||
}
|
||||
catch (Throwable mfe)
|
||||
{
|
||||
|
||||
LOG.warn(mfe);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue