Reformat and reindent code.

This commit is contained in:
Jan Bartel 2012-05-09 09:33:44 +02:00
parent d0f35d10fd
commit eae1b01122
18 changed files with 992 additions and 999 deletions

View File

@ -55,25 +55,29 @@ import org.osgi.framework.Constants;
* <p> * <p>
* When the parameter autoInstallOSGiBundles is set to true, OSGi bundles that * When the parameter autoInstallOSGiBundles is set to true, OSGi bundles that
* are located in the monitored directory are installed and started after the * are located in the monitored directory are installed and started after the
* framework as finished auto-starting all the other bundles. * framework as finished auto-starting all the other bundles. Warning: only use
* Warning: only use this for development. * this for development.
* </p> * </p>
*/ */
public class OSGiAppProvider extends ScanningAppProvider implements AppProvider public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
{ {
private static final Logger LOG = Log.getLogger(OSGiAppProvider.class); private static final Logger LOG = Log.getLogger(OSGiAppProvider.class);
private boolean _extractWars = true; private boolean _extractWars = true;
private boolean _parentLoaderPriority = false; private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor; private String _defaultsDescriptor;
private String _tldBundles; private String _tldBundles;
private String[] _configurationClasses; private String[] _configurationClasses;
private boolean _autoInstallOSGiBundles = true; private boolean _autoInstallOSGiBundles = true;
//Keep track of the bundles that were installed and that are waiting for the // Keep track of the bundles that were installed and that are waiting for
//framework to complete its initialization. // the
// framework to complete its initialization.
Set<Bundle> _pendingBundlesToStart = null; Set<Bundle> _pendingBundlesToStart = null;
/** /**
@ -86,11 +90,8 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
public boolean accept(File dir, String name) public boolean accept(File dir, String name)
{ {
File file = new File(dir,name); File file = new File(dir, name);
if (fileMightBeAnOSGiBundle(file)) if (fileMightBeAnOSGiBundle(file)) { return true; }
{
return true;
}
if (!file.isDirectory()) if (!file.isDirectory())
{ {
String contextName = getDeployedAppName(name); String contextName = getDeployedAppName(name);
@ -105,8 +106,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
/** /**
* @param contextFileName * @param contextFileName for example myContext.xml
* for example myContext.xml
* @return The context, for example: myContext; null if this was not a * @return The context, for example: myContext; null if this was not a
* suitable contextFileName. * suitable contextFileName.
*/ */
@ -115,30 +115,35 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
String lowername = contextFileName.toLowerCase(); String lowername = contextFileName.toLowerCase();
if (lowername.endsWith(".xml")) if (lowername.endsWith(".xml"))
{ {
String contextName = contextFileName.substring(0,lowername.length() - ".xml".length()); String contextName = contextFileName.substring(0, lowername.length() - ".xml".length());
return contextName; return contextName;
} }
return null; return null;
} }
/** /**
* Reading the display name of a webapp is really not sufficient for indexing the various * Reading the display name of a webapp is really not sufficient for
* deployed ContextHandlers. * indexing the various deployed ContextHandlers.
* *
* @param context * @param context
* @return * @return
*/ */
private String getContextHandlerAppName(ContextHandler context) { private String getContextHandlerAppName(ContextHandler context)
{
String appName = context.getDisplayName(); String appName = context.getDisplayName();
if (appName == null || appName.length() == 0 || getDeployedApps().containsKey(appName)) { if (appName == null || appName.length() == 0 || getDeployedApps().containsKey(appName))
{
if (context instanceof WebAppContext) if (context instanceof WebAppContext)
{ {
appName = ((WebAppContext)context).getContextPath(); appName = ((WebAppContext) context).getContextPath();
if (getDeployedApps().containsKey(appName)) { if (getDeployedApps().containsKey(appName))
appName = "noDisplayName"+context.getClass().getSimpleName()+context.hashCode(); {
appName = "noDisplayName" + context.getClass().getSimpleName() + context.hashCode();
} }
} else { }
appName = "noDisplayName"+context.getClass().getSimpleName()+context.hashCode(); else
{
appName = "noDisplayName" + context.getClass().getSimpleName() + context.hashCode();
} }
} }
return appName; return appName;
@ -151,7 +156,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
public OSGiAppProvider() public OSGiAppProvider()
{ {
super(new Filter()); super(new Filter());
((Filter)super._filenameFilter)._enclosedInstance = this; ((Filter) super._filenameFilter)._enclosedInstance = this;
} }
/** /**
@ -185,11 +190,10 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
if (_configurationClasses != null && wah instanceof WebAppContext) if (_configurationClasses != null && wah instanceof WebAppContext)
{ {
((WebAppContext)wah).setConfigurationClasses(_configurationClasses); ((WebAppContext) wah).setConfigurationClasses(_configurationClasses);
} }
if (_defaultsDescriptor != null) if (_defaultsDescriptor != null) ((WebAppContext) wah).setDefaultsDescriptor(_defaultsDescriptor);
((WebAppContext)wah).setDefaultsDescriptor(_defaultsDescriptor);
return app.getContextHandler(); return app.getContextHandler();
} }
@ -205,8 +209,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
private static String getOriginId(Bundle contributor, String pathInBundle) private static String getOriginId(Bundle contributor, String pathInBundle)
{ {
return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() + return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() + (pathInBundle.startsWith("/") ? pathInBundle : "/" + pathInBundle);
(pathInBundle.startsWith("/") ? pathInBundle : "/" + pathInBundle);
} }
/** /**
@ -217,6 +220,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
{ {
addContext(getOriginId(contributor, pathInBundle), context); addContext(getOriginId(contributor, pathInBundle), context);
} }
/** /**
* @param context * @param context
* @throws Exception * @throws Exception
@ -226,18 +230,16 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
// TODO apply configuration specific to this provider // TODO apply configuration specific to this provider
if (context instanceof WebAppContext) if (context instanceof WebAppContext)
{ {
((WebAppContext)context).setExtractWAR(isExtract()); ((WebAppContext) context).setExtractWAR(isExtract());
} }
// wrap context as an App // wrap context as an App
App app = new App(getDeploymentManager(),this,originId,context); App app = new App(getDeploymentManager(), this, originId, context);
String appName = getContextHandlerAppName(context); String appName = getContextHandlerAppName(context);
getDeployedApps().put(appName,app); getDeployedApps().put(appName, app);
getDeploymentManager().addApp(app); getDeploymentManager().addApp(app);
} }
/** /**
* Called by the scanner of the context files directory. If we find the * Called by the scanner of the context files directory. If we find the
* corresponding deployed App we reload it by returning the App. Otherwise * corresponding deployed App we reload it by returning the App. Otherwise
@ -254,10 +256,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
// and reload the corresponding App. // and reload the corresponding App.
// see the 2 pass of the refactoring of the WebAppRegistrationHelper. // see the 2 pass of the refactoring of the WebAppRegistrationHelper.
String name = getDeployedAppName(filename); String name = getDeployedAppName(filename);
if (name != null) if (name != null) { return getDeployedApps().get(name); }
{
return getDeployedApps().get(name);
}
return null; return null;
} }
@ -265,18 +264,22 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
{ {
String appName = getContextHandlerAppName(context); String appName = getContextHandlerAppName(context);
App app = getDeployedApps().remove(context.getDisplayName()); App app = getDeployedApps().remove(context.getDisplayName());
if (app == null) { if (app == null)
//try harder to undeploy this context handler. {
//see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=330098 // try harder to undeploy this context handler.
// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=330098
appName = null; appName = null;
for (Entry<String,App> deployedApp : getDeployedApps().entrySet()) { for (Entry<String, App> deployedApp : getDeployedApps().entrySet())
if (deployedApp.getValue().getContextHandler() == context) { {
if (deployedApp.getValue().getContextHandler() == context)
{
app = deployedApp.getValue(); app = deployedApp.getValue();
appName = deployedApp.getKey(); appName = deployedApp.getKey();
break; break;
} }
} }
if (appName != null) { if (appName != null)
{
getDeployedApps().remove(appName); getDeployedApps().remove(appName);
} }
} }
@ -303,8 +306,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
/** /**
* Set the parentLoaderPriority. * Set the parentLoaderPriority.
* *
* @param parentLoaderPriority * @param parentLoaderPriority the parentLoaderPriority to set
* the parentLoaderPriority to set
*/ */
public void setParentLoaderPriority(boolean parentLoaderPriority) public void setParentLoaderPriority(boolean parentLoaderPriority)
{ {
@ -326,8 +328,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
/** /**
* Set the defaultsDescriptor. * Set the defaultsDescriptor.
* *
* @param defaultsDescriptor * @param defaultsDescriptor the defaultsDescriptor to set
* the defaultsDescriptor to set
*/ */
public void setDefaultsDescriptor(String defaultsDescriptor) public void setDefaultsDescriptor(String defaultsDescriptor)
{ {
@ -343,8 +344,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
try try
{ {
Resource monitoredDir = getMonitoredDirResource(); Resource monitoredDir = getMonitoredDirResource();
if (monitoredDir == null) if (monitoredDir == null) return null;
return null;
return monitoredDir.getFile(); return monitoredDir.getFile();
} }
catch (IOException e) catch (IOException e)
@ -364,8 +364,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
try try
{ {
Resource monitoredDir = getMonitoredDirResource(); Resource monitoredDir = getMonitoredDirResource();
if (monitoredDir == null) if (monitoredDir == null) return null;
return null;
return monitoredDir.getFile().toURI().toString(); return monitoredDir.getFile().toURI().toString();
} }
catch (IOException e) catch (IOException e)
@ -382,12 +381,13 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
public void setExtract(boolean extract) public void setExtract(boolean extract)
{ {
_extractWars=extract; _extractWars = extract;
} }
/** /**
* @return true when this app provider locates osgi bundles and features in * @return true when this app provider locates osgi bundles and features in
* its monitored directory and installs them. By default true if there is a folder to monitor. * its monitored directory and installs them. By default true if
* there is a folder to monitor.
*/ */
public boolean isAutoInstallOSGiBundles() public boolean isAutoInstallOSGiBundles()
{ {
@ -396,14 +396,14 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
/** /**
* &lt;autoInstallOSGiBundles&gt;true&lt;/autoInstallOSGiBundles&gt; * &lt;autoInstallOSGiBundles&gt;true&lt;/autoInstallOSGiBundles&gt;
*
* @param installingOSGiBundles * @param installingOSGiBundles
*/ */
public void setAutoInstallOSGiBundles(boolean installingOSGiBundles) public void setAutoInstallOSGiBundles(boolean installingOSGiBundles)
{ {
_autoInstallOSGiBundles=installingOSGiBundles; _autoInstallOSGiBundles = installingOSGiBundles;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Set the directory in which to look for context XML files. * Set the directory in which to look for context XML files.
@ -435,8 +435,8 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
/** /**
* @return The list of bundles that contain tld jars that should be setup * @return The list of bundles that contain tld jars that should be setup on
* on the jetty instances created here. * the jetty instances created here.
*/ */
public String getTldBundles() public String getTldBundles()
{ {
@ -448,7 +448,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
*/ */
public void setConfigurationClasses(String[] configurations) public void setConfigurationClasses(String[] configurations)
{ {
_configurationClasses = configurations==null?null:(String[])configurations.clone(); _configurationClasses = configurations == null ? null : (String[]) configurations.clone();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -513,8 +513,8 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
/** /**
* When the file is a jar or a folder, we look if it looks like an OSGi bundle. * When the file is a jar or a folder, we look if it looks like an OSGi
* In that case we install it and start it. * bundle. In that case we install it and start it.
* <p> * <p>
* Really a simple trick to get going quickly with development. * Really a simple trick to get going quickly with development.
* </p> * </p>
@ -541,15 +541,9 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
{ {
if (file.isDirectory()) if (file.isDirectory())
{ {
if (new File(file,"META-INF/MANIFEST.MF").exists()) if (new File(file, "META-INF/MANIFEST.MF").exists()) { return true; }
{
return true;
}
}
else if (file.getName().endsWith(".jar"))
{
return true;
} }
else if (file.getName().endsWith(".jar")) { return true; }
return false; return false;
} }
@ -582,22 +576,21 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
/** /**
* Returns a bundle according to its location. * Returns a bundle according to its location. In the version 1.6 of
* In the version 1.6 of org.osgi.framework, BundleContext.getBundle(String) is what we want. * org.osgi.framework, BundleContext.getBundle(String) is what we want.
* However to support older versions of OSGi. We use our own local refrence mechanism. * However to support older versions of OSGi. We use our own local refrence
* mechanism.
*
* @param location * @param location
* @return * @return
*/ */
protected Bundle getBundle(BundleContext bc, String location) protected Bundle getBundle(BundleContext bc, String location)
{ {
//not available in older versions of OSGi: // not available in older versions of OSGi:
//return bc.getBundle(location); // return bc.getBundle(location);
for (Bundle b : bc.getBundles()) for (Bundle b : bc.getBundles())
{ {
if (b.getLocation().equals(location)) if (b.getLocation().equals(location)) { return b; }
{
return b;
}
} }
return null; return null;
} }
@ -616,13 +609,14 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
if (b == null) if (b == null)
{ {
//not sure we will ever be here, // not sure we will ever be here,
//most likely a BundleException was thrown // most likely a BundleException was thrown
LOG.warn("The file " + location + " is not an OSGi bundle."); LOG.warn("The file " + location + " is not an OSGi bundle.");
return null; return null;
} }
if (start && b.getHeaders().get(Constants.FRAGMENT_HOST) == null) if (start && b.getHeaders().get(Constants.FRAGMENT_HOST) == null)
{//not a fragment, try to start it. if the framework has finished auto-starting. {// not a fragment, try to start it. if the framework has finished
// auto-starting.
if (!PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts()) if (!PackageAdminServiceTracker.INSTANCE.frameworkHasCompletedAutostarts())
{ {
if (_pendingBundlesToStart == null) if (_pendingBundlesToStart == null)
@ -641,7 +635,7 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
catch (BundleException e) catch (BundleException e)
{ {
LOG.warn("Unable to " + (start? "start":"install") + " the bundle " + file.getAbsolutePath(), e); LOG.warn("Unable to " + (start ? "start" : "install") + " the bundle " + file.getAbsolutePath(), e);
} }
return null; return null;
} }
@ -684,11 +678,11 @@ public class OSGiAppProvider extends ScanningAppProvider implements AppProvider
} }
} }
} }
/** /**
* At the end of each scan, if there are some bundles to be started, * At the end of each scan, if there are some bundles to be started, look if the
* look if the framework has completed its autostart. In that case start those bundles. * framework has completed its autostart. In that case start those bundles.
*/ */
class AutoStartWhenFrameworkHasCompleted implements Scanner.ScanCycleListener class AutoStartWhenFrameworkHasCompleted implements Scanner.ScanCycleListener
{ {
@ -732,4 +726,3 @@ class AutoStartWhenFrameworkHasCompleted implements Scanner.ScanCycleListener
} }
} }

View File

@ -32,14 +32,14 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
/** /**
* Called by the {@link JettyBootstrapActivator} during the starting of the bundle. * Called by the {@link JettyBootstrapActivator} during the starting of the
* If the system property 'jetty.home' is defined and points to a folder, * bundle. If the system property 'jetty.home' is defined and points to a
* then setup the corresponding jetty server and starts it. * folder, then setup the corresponding jetty server and starts it.
*/ */
public class DefaultJettyAtJettyHomeHelper { public class DefaultJettyAtJettyHomeHelper
{
private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class); private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class);
/** /**
* contains a comma separated list of pathes to the etc/jetty-*.xml files * 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 * used to configure jetty. By default the value is 'etc/jetty.xml' when the
@ -48,44 +48,55 @@ public class DefaultJettyAtJettyHomeHelper {
public static final String SYS_PROP_JETTY_ETC_FILES = OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS; public static final String SYS_PROP_JETTY_ETC_FILES = OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS;
/** /**
* Usual system property used as the hostname for a typical jetty configuration. * Usual system property used as the hostname for a typical jetty
* configuration.
*/ */
public static final String SYS_PROP_JETTY_HOME = "jetty.home"; public static final String SYS_PROP_JETTY_HOME = "jetty.home";
/** /**
* System property to point to a bundle that embeds a jetty configuration * System property to point to a bundle that embeds a jetty configuration
* and that jetty configuration should be the default jetty server. * and that jetty configuration should be the default jetty server. First we
* First we look for jetty.home. If we don't find it then we look for this property. * look for jetty.home. If we don't find it then we look for this property.
*/ */
public static final String SYS_PROP_JETTY_HOME_BUNDLE = "jetty.home.bundle"; public static final String SYS_PROP_JETTY_HOME_BUNDLE = "jetty.home.bundle";
/** /**
* Usual system property used as the hostname for a typical jetty configuration. * Usual system property used as the hostname for a typical jetty
* configuration.
*/ */
public static final String SYS_PROP_JETTY_HOST = "jetty.host"; public static final String SYS_PROP_JETTY_HOST = "jetty.host";
/** /**
* Usual system property used as the port for http for a typical jetty configuration. * Usual system property used as the port for http for a typical jetty
* configuration.
*/ */
public static final String SYS_PROP_JETTY_PORT = "jetty.port"; public static final String SYS_PROP_JETTY_PORT = "jetty.port";
/** /**
* Usual system property used as the port for https for a typical jetty configuration. * 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"; public static final String SYS_PROP_JETTY_PORT_SSL = "jetty.port.ssl";
/** /**
* Called by the JettyBootStrapActivator. * Called by the JettyBootStrapActivator. If the system property jetty.home
* If the system property jetty.home is defined and points to a folder, * is defined and points to a folder, deploys the corresponding jetty
* deploys the corresponding jetty server. * server.
* <p> * <p>
* If the system property jetty.home.bundle is defined and points to a bundle. * If the system property jetty.home.bundle is defined and points to a
* Look for the configuration of jetty inside that bundle and deploys the corresponding bundle. * bundle. Look for the configuration of jetty inside that bundle and
* deploys the corresponding bundle.
* </p> * </p>
* <p> * <p>
* In both cases reads the system property 'jetty.etc.config.urls' to locate the configuration * In both cases reads the system property 'jetty.etc.config.urls' to locate
* files for the deployed jetty. It is a comma spearate list of URLs or relative paths inside the bundle or folder * the configuration files for the deployed jetty. It is a comma spearate
* to the config files. If underfined it defaults to 'etc/jetty.xml'. * list of URLs or relative paths inside the bundle or folder to the config
* files. If underfined it defaults to 'etc/jetty.xml'.
* </p> * </p>
* <p> * <p>
* In both cases the system properties jetty.host, jetty.port and jetty.port.ssl are passed to the configuration files * In both cases the system properties jetty.host, jetty.port and
* that might use them as part of their properties. * jetty.port.ssl are passed to the configuration files that might use them
* as part of their properties.
* </p> * </p>
*/ */
public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception
@ -97,15 +108,14 @@ public class DefaultJettyAtJettyHomeHelper {
if (jettyHomeSysProp != null) if (jettyHomeSysProp != null)
{ {
jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp); jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp);
//bug 329621 // bug 329621
if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'")))
|| (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) { {
jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1); jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1);
} }
if (jettyHomeBundleSysProp != null) if (jettyHomeBundleSysProp != null)
{ {
LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined." LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined." + " jetty.home.bundle is not taken into account.");
+ " jetty.home.bundle is not taken into account.");
} }
jettyHome = new File(jettyHomeSysProp); jettyHome = new File(jettyHomeSysProp);
if (!jettyHome.exists() || !jettyHome.isDirectory()) if (!jettyHome.exists() || !jettyHome.isDirectory())
@ -147,11 +157,12 @@ public class DefaultJettyAtJettyHomeHelper {
LOG.info("Configuring the default jetty server with " + configURLs); LOG.info("Configuring the default jetty server with " + configURLs);
//these properties usually are the ones passed to this type of configuration. // these properties usually are the ones passed to this type of
setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME)); // configuration.
setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST)); setProperty(properties, SYS_PROP_JETTY_HOME, System.getProperty(SYS_PROP_JETTY_HOME));
setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT)); setProperty(properties, SYS_PROP_JETTY_HOST, System.getProperty(SYS_PROP_JETTY_HOST));
setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL)); 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); bundleContext.registerService(Server.class.getName(), server, properties);
// hookNestedConnectorToBridgeServlet(server); // hookNestedConnectorToBridgeServlet(server);
@ -159,9 +170,11 @@ public class DefaultJettyAtJettyHomeHelper {
} }
/** /**
* Minimum setup for the location of the configuration files given a jettyhome folder. * Minimum setup for the location of the configuration files given a
* Reads the system property jetty.etc.config.urls and look for the corresponding jetty * jettyhome folder. Reads the system property jetty.etc.config.urls and
* configuration files that will be used to setup the jetty server. * look for the corresponding jetty configuration files that will be used to
* setup the jetty server.
*
* @param jettyhome * @param jettyhome
* @return * @return
*/ */
@ -191,17 +204,18 @@ public class DefaultJettyAtJettyHomeHelper {
} }
/** /**
* Minimum setup for the location of the configuration files given a configuration * Minimum setup for the location of the configuration files given a
* embedded inside a bundle. * configuration embedded inside a bundle. Reads the system property
* Reads the system property jetty.etc.config.urls and look for the corresponding jetty * jetty.etc.config.urls and look for the corresponding jetty configuration
* configuration files that will be used to setup the jetty server. * files that will be used to setup the jetty server.
*
* @param jettyhome * @param jettyhome
* @return * @return
*/ */
private static String getJettyConfigurationURLs(Bundle configurationBundle) 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); StringTokenizer tokenizer = new StringTokenizer(jettyetc, ";,", false);
StringBuilder res = new StringBuilder(); StringBuilder res = new StringBuilder();
while (tokenizer.hasMoreTokens()) while (tokenizer.hasMoreTokens())
@ -213,18 +227,18 @@ public class DefaultJettyAtJettyHomeHelper {
} }
else else
{ {
Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT.findEntries(configurationBundle, etcFile);
.findEntries(configurationBundle, etcFile);
//default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration. // default for org.eclipse.osgi.boot where we look inside
//default inside jettyhome. this way fragments to the bundle can define their own configuration. // 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")) if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml"))
{ {
enUrls = BundleFileLocatorHelper.DEFAULT enUrls = BundleFileLocatorHelper.DEFAULT.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml"); System.err.println("Configuring jetty with the default embedded configuration:" + "bundle: "
System.err.println("Configuring jetty with the default embedded configuration:" + + configurationBundle.getSymbolicName()
"bundle: " + configurationBundle.getSymbolicName() + + " config: /jettyhome/etc/jetty-osgi-default.xml");
" config: /jettyhome/etc/jetty-osgi-default.xml");
} }
if (enUrls == null || !enUrls.hasMoreElements()) if (enUrls == null || !enUrls.hasMoreElements())
{ {
@ -261,8 +275,9 @@ public class DefaultJettyAtJettyHomeHelper {
/** /**
* recursively substitute the ${sysprop} by their actual system property. * recursively substitute the ${sysprop} by their actual system property.
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined. * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no
* Not the most efficient code but we are shooting for simplicity and speed of development here. * sysprop is defined. Not the most efficient code but we are shooting for
* simplicity and speed of development here.
* *
* @param value * @param value
* @return * @return
@ -270,21 +285,17 @@ public class DefaultJettyAtJettyHomeHelper {
public static String resolvePropertyValue(String value) public static String resolvePropertyValue(String value)
{ {
int ind = value.indexOf("${"); int ind = value.indexOf("${");
if (ind == -1) { if (ind == -1) { return value; }
return value;
}
int ind2 = value.indexOf('}', ind); int ind2 = value.indexOf('}', ind);
if (ind2 == -1) { if (ind2 == -1) { return value; }
return value; String sysprop = value.substring(ind + 2, ind2);
}
String sysprop = value.substring(ind+2, ind2);
String defaultValue = null; String defaultValue = null;
int comma = sysprop.indexOf(','); int comma = sysprop.indexOf(',');
if (comma != -1 && comma+1 != sysprop.length()) if (comma != -1 && comma + 1 != sysprop.length())
{ {
defaultValue = sysprop.substring(comma+1); defaultValue = sysprop.substring(comma + 1);
defaultValue = resolvePropertyValue(defaultValue); defaultValue = resolvePropertyValue(defaultValue);
sysprop = sysprop.substring(0,comma); sysprop = sysprop.substring(0, comma);
} }
else else
{ {
@ -293,7 +304,7 @@ public class DefaultJettyAtJettyHomeHelper {
String v = System.getProperty(sysprop); String v = System.getProperty(sysprop);
String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : ""; String reminder = value.length() > ind2 + 1 ? value.substring(ind2 + 1) : "";
reminder = resolvePropertyValue(reminder); reminder = resolvePropertyValue(reminder);
if (v != null) if (v != null)
{ {

View File

@ -17,11 +17,13 @@ package org.eclipse.jetty.osgi.boot.internal.serverfactory;
/** /**
* Keeps track of the running jetty servers. They are named. * Keeps track of the running jetty servers. They are named.
*/ */
public interface IManagedJettyServerRegistry { public interface IManagedJettyServerRegistry
{
/** /**
* @param managedServerName The server name * @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); public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName);

View File

@ -86,7 +86,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
LOG.warn(e); LOG.warn(e);
} }
} }
}
if (ev.getType() == ServiceEvent.UNREGISTERING) if (ev.getType() == ServiceEvent.UNREGISTERING)
{ {
break; break;
@ -96,6 +96,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
// modified, meaning: we reload it. now that we stopped it; // modified, meaning: we reload it. now that we stopped it;
// we can register it. // we can register it.
} }
}
case ServiceEvent.REGISTERED: case ServiceEvent.REGISTERED:
{ {
try try

View File

@ -32,8 +32,8 @@ import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory; import org.osgi.service.cm.ManagedServiceFactory;
/** /**
* Manages the deployment of jetty server instances. * Manages the deployment of jetty server instances. Not sure this is bringing
* Not sure this is bringing much compared to the JettyServerServiceTracker. * much compared to the JettyServerServiceTracker.
* *
* @author hmalphettes * @author hmalphettes
*/ */
@ -45,6 +45,7 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
* is the corresponding java.io.File * is the corresponding java.io.File
*/ */
public static final String JETTY_HOME = "jettyhome"; public static final String JETTY_HOME = "jettyhome";
/** key to configure the server according to a jetty.xml file */ /** key to configure the server according to a jetty.xml file */
public static final String JETTY_CONFIG_XML = "jettyxml"; public static final String JETTY_CONFIG_XML = "jettyxml";
@ -58,6 +59,7 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
* default property in jetty.xml that is used as the value of the http port. * default property in jetty.xml that is used as the value of the http port.
*/ */
public static final String JETTY_HTTP_PORT = "jetty.http.port"; public static final String JETTY_HTTP_PORT = "jetty.http.port";
/** /**
* default property in jetty.xml that is used as the value of the https * default property in jetty.xml that is used as the value of the https
* port. * port.
@ -65,13 +67,16 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
public static final String JETTY_HTTPS_PORT = "jetty.http.port"; public static final String JETTY_HTTPS_PORT = "jetty.http.port";
/** /**
* 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> _serversIndexedByPID = new HashMap<String, ServerInstanceWrapper>(); private Map<String, ServerInstanceWrapper> _serversIndexedByPID = new HashMap<String, ServerInstanceWrapper>();
/** /**
* PID -> {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME} * PID -> {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME}
*/ */
private Map<String, String> _serversNameIndexedByPID = new HashMap<String, String>(); private Map<String, String> _serversNameIndexedByPID = new HashMap<String, String>();
/** /**
* {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME} -> PID * {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME} -> PID
*/ */
@ -96,12 +101,8 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
// to be able to re-deploy them later? // to be able to re-deploy them later?
// probably not. simply restart and see the various service trackers // probably not. simply restart and see the various service trackers
// do everything that is needed. // do everything that is needed.
String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); String name = (String) properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
if (name == null) 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); serverInstanceWrapper = new ServerInstanceWrapper(name);
_serversIndexedByPID.put(pid, serverInstanceWrapper); _serversIndexedByPID.put(pid, serverInstanceWrapper);
_serversNameIndexedByPID.put(pid, name); _serversNameIndexedByPID.put(pid, name);
@ -118,7 +119,7 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
public synchronized void deleted(String pid) public synchronized void deleted(String pid)
{ {
ServerInstanceWrapper server = (ServerInstanceWrapper)_serversIndexedByPID.remove(pid); ServerInstanceWrapper server = (ServerInstanceWrapper) _serversIndexedByPID.remove(pid);
String name = _serversNameIndexedByPID.remove(pid); String name = _serversNameIndexedByPID.remove(pid);
if (name != null) if (name != null)
{ {
@ -126,7 +127,7 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
} }
else else
{ {
//something incorrect going on. // something incorrect going on.
} }
if (server != null) if (server != null)
{ {
@ -148,7 +149,8 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
/** /**
* @param managedServerName The server name * @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) public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
{ {
@ -157,7 +159,9 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
} }
/** /**
* Helper method to create and configure a new Jetty Server via the ManagedServiceFactory * Helper method to create and configure a new Jetty Server via the
* ManagedServiceFactory
*
* @param contributor * @param contributor
* @param serverName * @param serverName
* @param urlsToJettyXml * @param urlsToJettyXml
@ -165,14 +169,11 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
*/ */
public static void createNewServer(Bundle contributor, String serverName, String urlsToJettyXml) throws Exception public static void createNewServer(Bundle contributor, String serverName, String urlsToJettyXml) throws Exception
{ {
ServiceReference configurationAdminReference = ServiceReference configurationAdminReference = contributor.getBundleContext().getServiceReference(ConfigurationAdmin.class.getName());
contributor.getBundleContext().getServiceReference( ConfigurationAdmin.class.getName() );
ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext() ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext().getService(configurationAdminReference);
.getService( configurationAdminReference );
Configuration configuration = confAdmin.createFactoryConfiguration( Configuration configuration = confAdmin.createFactoryConfiguration(OSGiServerConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation());
OSGiServerConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation() );
Dictionary properties = new Hashtable(); Dictionary properties = new Hashtable();
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName); properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName);
@ -187,12 +188,12 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
String token = tokenizer.nextToken(); String token = tokenizer.nextToken();
if (token.indexOf(':') != -1) if (token.indexOf(':') != -1)
{ {
//a complete url. no change needed: // a complete url. no change needed:
actualBundleUrls.append(token); actualBundleUrls.append(token);
} }
else if (token.startsWith("/")) else if (token.startsWith("/"))
{ {
//url relative to the contributor bundle: // url relative to the contributor bundle:
URL url = contributor.getEntry(token); URL url = contributor.getEntry(token);
if (url == null) if (url == null)
{ {

View File

@ -186,7 +186,6 @@ public class ServerInstanceWrapper
Thread.currentThread().setContextClassLoader(contextCl); Thread.currentThread().setContextClassLoader(contextCl);
} }
} }
public void stop() public void stop()

View File

@ -20,40 +20,37 @@ import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
/** /**
* Internal interface for the class that deploys a webapp on a server. * Internal interface for the class that deploys a webapp on a server. Used as
* Used as we migrate from the single instance of the jety server to multiple jetty servers. * we migrate from the single instance of the jety server to multiple jetty
* servers.
*/ */
public interface IWebBundleDeployerHelper { public interface IWebBundleDeployerHelper
{
/** when this property is present, the type of context handler registered is not /**
* known in advance. */ * when this property is present, the type of context handler registered is
* not known in advance.
*/
public static final String INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE = "unknownContextHandlerType"; public static final String INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE = "unknownContextHandlerType";
/** /**
* Deploy a new web application on the jetty server. * Deploy a new web application on the jetty server.
* *
* @param bundle * @param bundle The bundle
* The bundle * @param webappFolderPath The path to the root of the webapp. Must be a
* @param webappFolderPath * path relative to bundle; either an absolute path.
* The path to the root of the webapp. Must be a path relative to * @param contextPath The context path. Must start with "/"
* bundle; either an absolute path.
* @param contextPath
* The context path. Must start with "/"
* @param extraClasspath * @param extraClasspath
* @param overrideBundleInstallLocation * @param overrideBundleInstallLocation
* @param requireTldBundle The list of bundles's symbolic names that contain * @param requireTldBundle The list of bundles's symbolic names that contain
* tld files that are required by this WAB. * tld files that are required by this WAB.
* @param webXmlPath * @param webXmlPath
* @param defaultWebXmlPath * @param defaultWebXmlPath TODO: parameter description
* TODO: parameter description
* @return The contexthandler created and started * @return The contexthandler created and started
* @throws Exception * @throws Exception
*/ */
public abstract WebAppContext registerWebapplication(Bundle bundle, public abstract WebAppContext registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath, String extraClasspath,
String webappFolderPath, String contextPath, String extraClasspath, String overrideBundleInstallLocation, String requireTldBundle, String webXmlPath,
String overrideBundleInstallLocation,
String requireTldBundle, String webXmlPath,
String defaultWebXmlPath, WebAppContext webAppContext) throws Exception; String defaultWebXmlPath, WebAppContext webAppContext) throws Exception;
/** /**
@ -63,8 +60,7 @@ public interface IWebBundleDeployerHelper {
* @param contextHandler * @param contextHandler
* @throws Exception * @throws Exception
*/ */
public abstract void unregister(ContextHandler contextHandler) public abstract void unregister(ContextHandler contextHandler) throws Exception;
throws Exception;
/** /**
* This type of registration relies on jetty's complete context xml file. * This type of registration relies on jetty's complete context xml file.
@ -75,15 +71,14 @@ public interface IWebBundleDeployerHelper {
* @param contextFileRelativePath * @param contextFileRelativePath
* @param extraClasspath * @param extraClasspath
* @param overrideBundleInstallLocation * @param overrideBundleInstallLocation
* @param requireTldBundle The list of bundles'symbolic name that contain tld files for this webapp. * @param requireTldBundle The list of bundles'symbolic name that contain
* @param handler the context handler passed in the server * tld files for this webapp.
* reference that will be configured, deployed and started. * @param handler the context handler passed in the server reference that
* will be configured, deployed and started.
* @return The contexthandler created and started * @return The contexthandler created and started
* @throws Exception * @throws Exception
*/ */
public abstract ContextHandler registerContext(Bundle contributor, public abstract ContextHandler registerContext(Bundle contributor, String contextFileRelativePath, String extraClasspath,
String contextFileRelativePath, String extraClasspath, String overrideBundleInstallLocation, String requireTldBundle, ContextHandler handler) throws Exception;
String overrideBundleInstallLocation, String requireTldBundle,
ContextHandler handler) throws Exception;
} }

View File

@ -92,22 +92,18 @@ public class LibExtClassLoaderHelper
* is the JettyBootStrapper (an osgi classloader. * is the JettyBootStrapper (an osgi classloader.
* @throws MalformedURLException * @throws MalformedURLException
*/ */
public static ClassLoader createLibEtcClassLoader(File jettyHome, Server server, public static ClassLoader createLibEtcClassLoader(File jettyHome, Server server, ClassLoader parentClassLoader) throws MalformedURLException
ClassLoader parentClassLoader) throws MalformedURLException
{ {
if (jettyHome == null) if (jettyHome == null) { return parentClassLoader; }
{
return parentClassLoader;
}
ArrayList<URL> urls = new ArrayList<URL>(); ArrayList<URL> urls = new ArrayList<URL>();
File jettyResources = new File(jettyHome,"resources"); File jettyResources = new File(jettyHome, "resources");
if (jettyResources.exists()) if (jettyResources.exists())
{ {
// make sure it contains something else than README: // make sure it contains something else than README:
Map<String, File> jettyResFiles = new HashMap<String, File>(); Map<String, File> jettyResFiles = new HashMap<String, File>();
for (File f : jettyResources.listFiles()) for (File f : jettyResources.listFiles())
{ {
jettyResFiles.put(f.getName(),f); jettyResFiles.put(f.getName(), f);
if (f.getName().toLowerCase().startsWith("readme")) if (f.getName().toLowerCase().startsWith("readme"))
{ {
continue; continue;
@ -120,9 +116,9 @@ public class LibExtClassLoaderHelper
} }
} }
} }
processFilesInResourcesFolder(jettyHome,jettyResFiles); processFilesInResourcesFolder(jettyHome, jettyResFiles);
} }
File libExt = new File(jettyHome,"lib/ext"); File libExt = new File(jettyHome, "lib/ext");
if (libExt.exists()) if (libExt.exists())
{ {
for (File f : libExt.listFiles()) for (File f : libExt.listFiles())
@ -140,25 +136,20 @@ public class LibExtClassLoaderHelper
} }
} }
return new URLClassLoader(urls.toArray(new URL[urls.size()]),parentClassLoader); return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader);
} }
/** /**
* @param server * @param server
* @return a url classloader with the jars of resources, lib/ext and the * @return a url classloader with the jars of resources, lib/ext and the
* jars passed in the other argument. The parent classloader usually * jars passed in the other argument. The parent classloader usually
* is the JettyBootStrapper (an osgi classloader). * is the JettyBootStrapper (an osgi classloader). If there was no
* If there was no extra jars to insert, then just return the parentClassLoader. * extra jars to insert, then just return the parentClassLoader.
* @throws MalformedURLException * @throws MalformedURLException
*/ */
public static ClassLoader createLibExtClassLoader(List<File> jarsContainerOrJars, public static ClassLoader createLibExtClassLoader(List<File> jarsContainerOrJars, List<URL> otherJarsOrFolder, Server server, ClassLoader parentClassLoader) throws MalformedURLException
List<URL> otherJarsOrFolder, Server server,
ClassLoader parentClassLoader) throws MalformedURLException
{ {
if (jarsContainerOrJars == null && otherJarsOrFolder == null) if (jarsContainerOrJars == null && otherJarsOrFolder == null) { return parentClassLoader; }
{
return parentClassLoader;
}
List<URL> urls = new ArrayList<URL>(); List<URL> urls = new ArrayList<URL>();
if (otherJarsOrFolder != null) if (otherJarsOrFolder != null)
{ {
@ -186,7 +177,7 @@ public class LibExtClassLoaderHelper
} }
} }
} }
return new URLClassLoader(urls.toArray(new URL[urls.size()]),parentClassLoader); return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader);
} }
/** /**
@ -207,7 +198,7 @@ public class LibExtClassLoaderHelper
{ {
for (IFilesInJettyHomeResourcesProcessor processor : registeredFilesInJettyHomeResourcesProcessors) for (IFilesInJettyHomeResourcesProcessor processor : registeredFilesInJettyHomeResourcesProcessors)
{ {
processor.processFilesInResourcesFolder(jettyHome,childrenFiles); processor.processFilesInResourcesFolder(jettyHome, childrenFiles);
} }
} }

View File

@ -55,12 +55,12 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
public static void addClassThatIdentifiesAJarThatMustBeRejected(Class<?> zclass) public static void addClassThatIdentifiesAJarThatMustBeRejected(Class<?> zclass)
{ {
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclass.getName().replace('.','/') + ".class"); JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclass.getName().replace('.', '/') + ".class");
} }
public static void addClassThatIdentifiesAJarThatMustBeRejected(String zclassName) public static void addClassThatIdentifiesAJarThatMustBeRejected(String zclassName)
{ {
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclassName.replace('.','/') + ".class"); JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclassName.replace('.', '/') + ".class");
} }
static static
@ -69,8 +69,11 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
} }
private ClassLoader _osgiBundleClassLoader; private ClassLoader _osgiBundleClassLoader;
private Bundle _contributor; private Bundle _contributor;
private boolean _lookInOsgiFirst = true; private boolean _lookInOsgiFirst = true;
private Set<String> _libsAlreadyInManifest = new HashSet<String>(); private Set<String> _libsAlreadyInManifest = new HashSet<String>();
/** /**
@ -79,10 +82,10 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
* @param contributor The bundle that defines this web-application. * @param contributor The bundle that defines this web-application.
* @throws IOException * @throws IOException
*/ */
public OSGiWebappClassLoader(ClassLoader parent, WebAppContext context, Bundle contributor, public OSGiWebappClassLoader(ClassLoader parent, WebAppContext context, Bundle contributor, BundleClassLoaderHelper bundleClassLoaderHelper)
BundleClassLoaderHelper bundleClassLoaderHelper) throws IOException throws IOException
{ {
super(parent,context); super(parent, context);
_contributor = contributor; _contributor = contributor;
_osgiBundleClassLoader = bundleClassLoaderHelper.getBundleClassLoader(contributor); _osgiBundleClassLoader = bundleClassLoaderHelper.getBundleClassLoader(contributor);
} }
@ -142,9 +145,9 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2) private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
{ {
List<URL> list = new ArrayList<URL>(); List<URL> list = new ArrayList<URL>();
while (e!=null && e.hasMoreElements()) while (e != null && e.hasMoreElements())
list.add(e.nextElement()); list.add(e.nextElement());
while (e2!=null && e2.hasMoreElements()) while (e2 != null && e2.hasMoreElements())
list.add(e2.nextElement()); list.add(e2.nextElement());
return list; return list;
} }
@ -156,13 +159,13 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
{ {
try try
{ {
return _lookInOsgiFirst?_osgiBundleClassLoader.loadClass(name):super.findClass(name); return _lookInOsgiFirst ? _osgiBundleClassLoader.loadClass(name) : super.findClass(name);
} }
catch (ClassNotFoundException cne) catch (ClassNotFoundException cne)
{ {
try try
{ {
return _lookInOsgiFirst?super.findClass(name):_osgiBundleClassLoader.loadClass(name); return _lookInOsgiFirst ? super.findClass(name) : _osgiBundleClassLoader.loadClass(name);
} }
catch (ClassNotFoundException cne2) catch (ClassNotFoundException cne2)
{ {
@ -179,7 +182,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
public void addClassPath(String classPath) throws IOException public void addClassPath(String classPath) throws IOException
{ {
StringTokenizer tokenizer = new StringTokenizer(classPath,",;"); StringTokenizer tokenizer = new StringTokenizer(classPath, ",;");
while (tokenizer.hasMoreTokens()) while (tokenizer.hasMoreTokens())
{ {
String path = tokenizer.nextToken(); String path = tokenizer.nextToken();
@ -187,7 +190,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
// Resolve file path if possible // Resolve file path if possible
File file = resource.getFile(); File file = resource.getFile();
if (file != null && isAcceptableLibrary(file,JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED)) if (file != null && isAcceptableLibrary(file, JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED))
{ {
super.addClassPath(path); super.addClassPath(path);
} }
@ -211,10 +214,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
{ {
for (String criteria : pathToClassFiles) for (String criteria : pathToClassFiles)
{ {
if (new File(file,criteria).exists()) if (new File(file, criteria).exists()) { return false; }
{
return false;
}
} }
} }
else else
@ -225,16 +225,12 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
jar = new JarFile(file); jar = new JarFile(file);
for (String criteria : pathToClassFiles) for (String criteria : pathToClassFiles)
{ {
if (jar.getEntry(criteria) != null) if (jar.getEntry(criteria) != null) { return false; }
{
return false;
}
} }
} }
finally finally
{ {
if (jar != null) if (jar != null) try
try
{ {
jar.close(); jar.close();
} }
@ -270,7 +266,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
_contextField = WebAppClassLoader.class.getDeclaredField("_context"); _contextField = WebAppClassLoader.class.getDeclaredField("_context");
_contextField.setAccessible(true); _contextField.setAccessible(true);
} }
_contextField.set(this,webappContext); _contextField.set(this, webappContext);
if (webappContext.getExtraClasspath() != null) if (webappContext.getExtraClasspath() != null)
{ {
addClassPath(webappContext.getExtraClasspath()); addClassPath(webappContext.getExtraClasspath());

View File

@ -230,9 +230,9 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
try try
{ {
// apply any META-INF/context.xml file that is found to configure
//apply any META-INF/context.xml file that is found to configure the webapp first // the webapp first
applyMetaInfContextXml (contributor, context); applyMetaInfContextXml(contributor, context);
// make sure we provide access to all the jetty bundles by going // make sure we provide access to all the jetty bundles by going
// through this bundle. // through this bundle.
@ -242,7 +242,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
// that the contributor gives access to. // that the contributor gives access to.
Thread.currentThread().setContextClassLoader(composite); Thread.currentThread().setContextClassLoader(composite);
//converts bundleentry: protocol // converts bundleentry: protocol
baseWebappInstallURL = DefaultFileLocatorHelper.getLocalURL(baseWebappInstallURL); baseWebappInstallURL = DefaultFileLocatorHelper.getLocalURL(baseWebappInstallURL);
context.setWar(baseWebappInstallURL.toString()); context.setWar(baseWebappInstallURL.toString());
@ -455,9 +455,7 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
Thread.currentThread().setContextClassLoader(composite); Thread.currentThread().setContextClassLoader(composite);
ContextHandler context = createContextHandler(handler, contributor, contextFileInputStream, extraClasspath, overrideBundleInstallLocation, ContextHandler context = createContextHandler(handler, contributor, contextFileInputStream, extraClasspath, overrideBundleInstallLocation,
requireTldBundle); requireTldBundle);
if (context == null) if (context == null) { return null;// did not happen
{
return null;// did not happen
} }
// ok now register this webapp. we checked when we started jetty // ok now register this webapp. we checked when we started jetty
@ -810,28 +808,23 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
return webappClassLoader; return webappClassLoader;
} }
protected void applyMetaInfContextXml(Bundle bundle, ContextHandler contextHandler) throws Exception
protected void applyMetaInfContextXml (Bundle bundle, ContextHandler contextHandler)
throws Exception
{ {
if (bundle == null) if (bundle == null) return;
return; if (contextHandler == null) return;
if (contextHandler == null)
return;
ClassLoader cl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = Thread.currentThread().getContextClassLoader();
__logger.info("Context classloader = "+cl); __logger.info("Context classloader = " + cl);
try try
{ {
Thread.currentThread().setContextClassLoader(_wrapper.getParentClassLoaderForWebapps()); Thread.currentThread().setContextClassLoader(_wrapper.getParentClassLoaderForWebapps());
//find if there is a META-INF/context.xml file // find if there is a META-INF/context.xml file
URL contextXmlUrl = bundle.getEntry("/META-INF/jetty-webapp-context.xml"); URL contextXmlUrl = bundle.getEntry("/META-INF/jetty-webapp-context.xml");
if (contextXmlUrl == null) if (contextXmlUrl == null) return;
return;
//Apply it just as the standard jetty ContextProvider would do // Apply it just as the standard jetty ContextProvider would do
__logger.info("Applying "+contextXmlUrl+" to "+contextHandler); __logger.info("Applying " + contextXmlUrl + " to " + contextHandler);
XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl); XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl);
HashMap properties = new HashMap(); HashMap properties = new HashMap();
@ -845,8 +838,6 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
} }
} }
/** /**
* Set the property &quot;this.bundle.install&quot; to point to the location * Set the property &quot;this.bundle.install&quot; to point to the location
* of the bundle. Useful when <SystemProperty name="this.bundle.home"/> is * of the bundle. Useful when <SystemProperty name="this.bundle.home"/> is
@ -883,11 +874,10 @@ public class WebBundleDeployerHelper implements IWebBundleDeployerHelper
+ "' specified in the " + "' specified in the "
+ OSGiWebappConstants.REQUIRE_TLD_BUNDLE + OSGiWebappConstants.REQUIRE_TLD_BUNDLE
+ " of the manifest of " + " of the manifest of "
+ (bundle==null?"unknown":bundle.getSymbolicName())); } + (bundle == null ? "unknown" : bundle.getSymbolicName())); }
File f = fileLocatorHelper.getBundleInstallLocation(bs[0]); File f = fileLocatorHelper.getBundleInstallLocation(bs[0]);
if (paths.length() > 0) if (paths.length() > 0) paths.append(", ");
paths.append(", ");
__logger.debug("getPathsToRequiredBundles: bundle path=" + bs[0].getLocation() + " uri=" + f.toURI()); __logger.debug("getPathsToRequiredBundles: bundle path=" + bs[0].getLocation() + " uri=" + f.toURI());
paths.append(f.toURI().toURL().toString()); paths.append(f.toURI().toURL().toString());
} }

View File

@ -167,7 +167,8 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
catch (Throwable e) catch (Throwable e)
{ {
LOG.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e); LOG.warn("Starting the web-bundle " + bundle.getSymbolicName() + " threw an exception.", e);
return true;// maybe it did not work maybe it did. safer to track this bundle. return true;// maybe it did not work maybe it did. safer to
// track this bundle.
} }
} }
else if (dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH) != null) else if (dic.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH) != null)
@ -199,9 +200,10 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
// (draft) of the spec: just a couple of posts on the // (draft) of the spec: just a couple of posts on the
// world-wide-web. // world-wide-web.
URL rfc66Webxml = bundle.getEntry("/WEB-INF/web.xml"); URL rfc66Webxml = bundle.getEntry("/WEB-INF/web.xml");
if (rfc66Webxml == null && dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) == null) if (rfc66Webxml == null && dic.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) == null) { return false;// no
{ // webapp
return false;// no webapp in here // in
// here
} }
// this is risky: should we make sure that there is no classes and // this is risky: should we make sure that there is no classes and
// jars directly available // jars directly available
@ -220,7 +222,8 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
catch (Throwable e) catch (Throwable e)
{ {
LOG.warn(e); LOG.warn(e);
return true;// maybe it did not work maybe it did. safer to track this bundle. return true;// maybe it did not work maybe it did. safer to
// track this bundle.
} }
} }
} }

View File

@ -34,7 +34,6 @@ public interface BundleFileLocatorHelper
/** The default instance supports felix and equinox */ /** The default instance supports felix and equinox */
public static BundleFileLocatorHelper DEFAULT = new DefaultFileLocatorHelper(); public static BundleFileLocatorHelper DEFAULT = new DefaultFileLocatorHelper();
/** /**
* Works with equinox, felix, nuxeo and probably more. Not exactly in the * Works with equinox, felix, nuxeo and probably more. Not exactly in the
* spirit of OSGi but quite necessary to support self-contained webapps and * spirit of OSGi but quite necessary to support self-contained webapps and
@ -43,8 +42,7 @@ public interface BundleFileLocatorHelper
* Currently only works with bundles that are not jar. * Currently only works with bundles that are not jar.
* </p> * </p>
* *
* @param bundle * @param bundle The bundle
* The bundle
* @return Its installation location as a file. * @return Its installation location as a file.
* @throws Exception * @throws Exception
*/ */
@ -76,7 +74,6 @@ public interface BundleFileLocatorHelper
*/ */
public File[] locateJarsInsideBundle(Bundle bundle) throws Exception; public File[] locateJarsInsideBundle(Bundle bundle) throws Exception;
/** /**
* Helper method equivalent to Bundle#getEntry(String entryPath) except that * Helper method equivalent to Bundle#getEntry(String entryPath) except that
* it searches for entries in the fragments by using the findEntries method. * it searches for entries in the fragments by using the findEntries method.

View File

@ -29,7 +29,9 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
{ {
private static boolean identifiedOsgiImpl = false; private static boolean identifiedOsgiImpl = false;
private static boolean isEquinox = false; private static boolean isEquinox = false;
private static boolean isFelix = false; private static boolean isFelix = false;
private static void init(Bundle bundle) private static void init(Bundle bundle)
@ -66,10 +68,10 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
*/ */
public ClassLoader getBundleClassLoader(Bundle bundle) public ClassLoader getBundleClassLoader(Bundle bundle)
{ {
String bundleActivator = (String)bundle.getHeaders().get("Bundle-Activator"); String bundleActivator = (String) bundle.getHeaders().get("Bundle-Activator");
if (bundleActivator == null) if (bundleActivator == null)
{ {
bundleActivator = (String)bundle.getHeaders().get("Jetty-ClassInBundle"); bundleActivator = (String) bundle.getHeaders().get("Jetty-ClassInBundle");
} }
if (bundleActivator != null) if (bundleActivator != null)
{ {
@ -93,14 +95,12 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
{ {
return internalGetEquinoxBundleClassLoader(bundle); return internalGetEquinoxBundleClassLoader(bundle);
} }
else if (isFelix) else if (isFelix) { return internalGetFelixBundleClassLoader(bundle); }
{
return internalGetFelixBundleClassLoader(bundle);
}
return null; return null;
} }
private static Method Equinox_BundleHost_getBundleLoader_method; private static Method Equinox_BundleHost_getBundleLoader_method;
private static Method Equinox_BundleLoader_createClassLoader_method; private static Method Equinox_BundleLoader_createClassLoader_method;
private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle) private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle)
@ -111,17 +111,18 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
if (Equinox_BundleHost_getBundleLoader_method == null) if (Equinox_BundleHost_getBundleLoader_method == null)
{ {
Equinox_BundleHost_getBundleLoader_method = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost") Equinox_BundleHost_getBundleLoader_method = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost")
.getDeclaredMethod("getBundleLoader",new Class[] {}); .getDeclaredMethod("getBundleLoader", new Class[] {});
Equinox_BundleHost_getBundleLoader_method.setAccessible(true); Equinox_BundleHost_getBundleLoader_method.setAccessible(true);
} }
Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle,new Object[] {}); Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle, new Object[] {});
if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null) if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null)
{ {
Equinox_BundleLoader_createClassLoader_method = bundleLoader.getClass().getClassLoader().loadClass( Equinox_BundleLoader_createClassLoader_method = bundleLoader.getClass().getClassLoader()
"org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader",new Class[] {}); .loadClass("org.eclipse.osgi.internal.loader.BundleLoader")
.getDeclaredMethod("createClassLoader", new Class[] {});
Equinox_BundleLoader_createClassLoader_method.setAccessible(true); Equinox_BundleLoader_createClassLoader_method.setAccessible(true);
} }
return (ClassLoader)Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader,new Object[] {}); return (ClassLoader) Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[] {});
} }
catch (Throwable t) catch (Throwable t)
{ {
@ -131,6 +132,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
} }
private static Field Felix_BundleImpl_m_modules_field; private static Field Felix_BundleImpl_m_modules_field;
private static Field Felix_ModuleImpl_m_classLoader_field; private static Field Felix_ModuleImpl_m_classLoader_field;
private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle) private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle)
@ -142,8 +144,8 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
// and return the private field m_classLoader of ModuleImpl // and return the private field m_classLoader of ModuleImpl
if (Felix_BundleImpl_m_modules_field == null) if (Felix_BundleImpl_m_modules_field == null)
{ {
Felix_BundleImpl_m_modules_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl").getDeclaredField( Felix_BundleImpl_m_modules_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl")
"m_modules"); .getDeclaredField("m_modules");
Felix_BundleImpl_m_modules_field.setAccessible(true); Felix_BundleImpl_m_modules_field.setAccessible(true);
} }
@ -151,26 +153,26 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
Object currentModuleImpl; Object currentModuleImpl;
try try
{ {
Object[] moduleArray = (Object[])Felix_BundleImpl_m_modules_field.get(bundle); Object[] moduleArray = (Object[]) Felix_BundleImpl_m_modules_field.get(bundle);
currentModuleImpl = moduleArray[moduleArray.length - 1]; currentModuleImpl = moduleArray[moduleArray.length - 1];
} }
catch (Throwable t2) catch (Throwable t2)
{ {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Object> moduleArray = (List<Object>)Felix_BundleImpl_m_modules_field.get(bundle); List<Object> moduleArray = (List<Object>) Felix_BundleImpl_m_modules_field.get(bundle);
currentModuleImpl = moduleArray.get(moduleArray.size() - 1); currentModuleImpl = moduleArray.get(moduleArray.size() - 1);
} }
if (Felix_ModuleImpl_m_classLoader_field == null && currentModuleImpl != null) if (Felix_ModuleImpl_m_classLoader_field == null && currentModuleImpl != null)
{ {
Felix_ModuleImpl_m_classLoader_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField( Felix_ModuleImpl_m_classLoader_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl")
"m_classLoader"); .getDeclaredField("m_classLoader");
Felix_ModuleImpl_m_classLoader_field.setAccessible(true); Felix_ModuleImpl_m_classLoader_field.setAccessible(true);
} }
// first make sure that the classloader is ready: // first make sure that the classloader is ready:
// the m_classLoader field must be initialized by the // the m_classLoader field must be initialized by the
// ModuleImpl.getClassLoader() private method. // ModuleImpl.getClassLoader() private method.
ClassLoader cl = (ClassLoader)Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl); ClassLoader cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
if (cl == null) if (cl == null)
{ {
// looks like it was not ready: // looks like it was not ready:
@ -178,7 +180,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
// ModuleImpl.getClassLoader() private method. // ModuleImpl.getClassLoader() private method.
// this call will do that. // this call will do that.
bundle.loadClass("java.lang.Object"); bundle.loadClass("java.lang.Object");
cl = (ClassLoader)Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl); cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
// System.err.println("Got the bundle class loader of felix_: " // System.err.println("Got the bundle class loader of felix_: "
// + cl); // + cl);
return cl; return cl;

View File

@ -84,7 +84,12 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
// the File // the File
URLConnection con = url.openConnection(); URLConnection con = url.openConnection();
con.setUseCaches(Resource.getDefaultUseCaches()); //work around problems where url connections cache references to jars con.setUseCaches(Resource.getDefaultUseCaches()); // work around
// problems where
// url connections
// cache
// references to
// jars
if (BUNDLE_ENTRY_FIELD == null) if (BUNDLE_ENTRY_FIELD == null)
{ {
@ -151,9 +156,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
// it is relative to relative to the BundleArchive's // it is relative to relative to the BundleArchive's
// m_archiveRootDir // m_archiveRootDir
File res = new File(location.substring("file:".length())); File res = new File(location.substring("file:".length()));
if (!res.exists()) if (!res.exists()) { return null;
{
return null;
// Object bundleArchive = getFelixBundleArchive(bundle); // Object bundleArchive = getFelixBundleArchive(bundle);
// File archiveRoot = // File archiveRoot =
// getFelixBundleArchiveRootDir(bundleArchive); // getFelixBundleArchiveRootDir(bundleArchive);
@ -194,15 +197,12 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
} }
File bundleInstall = getBundleInstallLocation(bundle); File bundleInstall = getBundleInstallLocation(bundle);
File webapp = path != null && path.length() != 0 ? new File(bundleInstall, path) : bundleInstall; File webapp = path != null && path.length() != 0 ? new File(bundleInstall, path) : bundleInstall;
if (!webapp.exists()) if (!webapp.exists()) { throw new IllegalArgumentException("Unable to locate " + path
{
throw new IllegalArgumentException("Unable to locate " + path
+ " inside " + " inside "
+ bundle.getSymbolicName() + bundle.getSymbolicName()
+ " (" + " ("
+ (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ") + (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ")
+ ")"); + ")"); }
}
return webapp; return webapp;
} }

View File

@ -37,10 +37,15 @@ public class PackageAdminServiceTracker implements ServiceListener
private BundleContext _context; private BundleContext _context;
private List<BundleActivator> _activatedFragments = new ArrayList<BundleActivator>(); private List<BundleActivator> _activatedFragments = new ArrayList<BundleActivator>();
private boolean _fragmentsWereActivated = false; private boolean _fragmentsWereActivated = false;
//Use the deprecated StartLevel to stay compatible with older versions of OSGi.
// Use the deprecated StartLevel to stay compatible with older versions of
// OSGi.
private StartLevel _startLevel; private StartLevel _startLevel;
private int _maxStartLevel = 6; private int _maxStartLevel = 6;
public static PackageAdminServiceTracker INSTANCE = null; public static PackageAdminServiceTracker INSTANCE = null;
public PackageAdminServiceTracker(BundleContext context) public PackageAdminServiceTracker(BundleContext context)
@ -51,7 +56,7 @@ public class PackageAdminServiceTracker implements ServiceListener
{ {
try try
{ {
_context.addServiceListener(this,"(objectclass=" + PackageAdmin.class.getName() + ")"); _context.addServiceListener(this, "(objectclass=" + PackageAdmin.class.getName() + ")");
} }
catch (InvalidSyntaxException e) catch (InvalidSyntaxException e)
{ {
@ -67,20 +72,19 @@ public class PackageAdminServiceTracker implements ServiceListener
{ {
ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName()); ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
_fragmentsWereActivated = sr != null; _fragmentsWereActivated = sr != null;
if (sr != null) if (sr != null) invokeFragmentActivators(sr);
invokeFragmentActivators(sr);
sr = _context.getServiceReference(StartLevel.class.getName()); sr = _context.getServiceReference(StartLevel.class.getName());
if (sr != null) if (sr != null)
{ {
_startLevel = (StartLevel)_context.getService(sr); _startLevel = (StartLevel) _context.getService(sr);
try try
{ {
_maxStartLevel = Integer.parseInt(System.getProperty("osgi.startLevel","6")); _maxStartLevel = Integer.parseInt(System.getProperty("osgi.startLevel", "6"));
} }
catch (Exception e) catch (Exception e)
{ {
//nevermind default on the usual. // nevermind default on the usual.
_maxStartLevel = 6; _maxStartLevel = 6;
} }
} }
@ -93,8 +97,7 @@ public class PackageAdminServiceTracker implements ServiceListener
* the symbolic name of the fragment and the name of the class must be * the symbolic name of the fragment and the name of the class must be
* 'FragmentActivator'. * 'FragmentActivator'.
* *
* @param event * @param event The <code>ServiceEvent</code> object.
* The <code>ServiceEvent</code> object.
*/ */
public void serviceChanged(ServiceEvent event) public void serviceChanged(ServiceEvent event)
{ {
@ -105,9 +108,10 @@ public class PackageAdminServiceTracker implements ServiceListener
} }
/** /**
* Helper to access the PackageAdmin and return the fragments hosted by a bundle. * Helper to access the PackageAdmin and return the fragments hosted by a
* when we drop the support for the older versions of OSGi, we will stop using the PackageAdmin * bundle. when we drop the support for the older versions of OSGi, we will
* service. * stop using the PackageAdmin service.
*
* @param bundle * @param bundle
* @return * @return
*/ */
@ -115,17 +119,18 @@ public class PackageAdminServiceTracker implements ServiceListener
{ {
ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName()); ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
if (sr == null) if (sr == null)
{//we should never be here really. {// we should never be here really.
return null; return null;
} }
PackageAdmin admin = (PackageAdmin)_context.getService(sr); PackageAdmin admin = (PackageAdmin) _context.getService(sr);
return admin.getFragments(bundle); return admin.getFragments(bundle);
} }
/** /**
* Returns the fragments and the required-bundles of a bundle. * Returns the fragments and the required-bundles of a bundle. Recursively
* Recursively collect the required-bundles and fragment when the directive visibility:=reexport * collect the required-bundles and fragment when the directive
* is added to a required-bundle. * visibility:=reexport is added to a required-bundle.
*
* @param bundle * @param bundle
* @param webFragOrAnnotationOrResources * @param webFragOrAnnotationOrResources
* @return * @return
@ -134,28 +139,32 @@ public class PackageAdminServiceTracker implements ServiceListener
{ {
ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName()); ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName());
if (sr == null) if (sr == null)
{//we should never be here really. {// we should never be here really.
return null; return null;
} }
PackageAdmin admin = (PackageAdmin)_context.getService(sr); PackageAdmin admin = (PackageAdmin) _context.getService(sr);
LinkedHashMap<String,Bundle> deps = new LinkedHashMap<String,Bundle>(); LinkedHashMap<String, Bundle> deps = new LinkedHashMap<String, Bundle>();
collectFragmentsAndRequiredBundles(bundle, admin, deps, false); collectFragmentsAndRequiredBundles(bundle, admin, deps, false);
return deps.values().toArray(new Bundle[deps.size()]); return deps.values().toArray(new Bundle[deps.size()]);
} }
/** /**
* Returns the fragments and the required-bundles. Collects them transitively when the directive 'visibility:=reexport' * Returns the fragments and the required-bundles. Collects them
* is added to a required-bundle. * transitively when the directive 'visibility:=reexport' is added to a
* required-bundle.
*
* @param bundle * @param bundle
* @param webFragOrAnnotationOrResources * @param webFragOrAnnotationOrResources
* @return * @return
*/ */
protected void collectFragmentsAndRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport) protected void collectFragmentsAndRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String, Bundle> deps, boolean onlyReexport)
{ {
Bundle[] fragments = admin.getFragments(bundle); Bundle[] fragments = admin.getFragments(bundle);
if (fragments != null) if (fragments != null)
{ {
//Also add the bundles required by the fragments. // Also add the bundles required by the fragments.
//this way we can inject onto an existing web-bundle a set of bundles that extend it // this way we can inject onto an existing web-bundle a set of
// bundles that extend it
for (Bundle f : fragments) for (Bundle f : fragments)
{ {
if (!deps.keySet().contains(f.getSymbolicName())) if (!deps.keySet().contains(f.getSymbolicName()))
@ -169,20 +178,20 @@ public class PackageAdminServiceTracker implements ServiceListener
} }
/** /**
* A simplistic but good enough parser for the Require-Bundle header. * A simplistic but good enough parser for the Require-Bundle header. Parses
* Parses the version range attribute and the visibility directive. * the version range attribute and the visibility directive.
* *
* @param onlyReexport true to collect resources and web-fragments transitively if and only if the directive visibility is reexport. * @param onlyReexport true to collect resources and web-fragments
* transitively if and only if the directive visibility is
* reexport.
* @param bundle * @param bundle
* @return The map of required bundles associated to the value of the jetty-web attribute. * @return The map of required bundles associated to the value of the
* jetty-web attribute.
*/ */
protected void collectRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String,Bundle> deps, boolean onlyReexport) protected void collectRequiredBundles(Bundle bundle, PackageAdmin admin, Map<String, Bundle> deps, boolean onlyReexport)
{ {
String requiredBundleHeader = (String)bundle.getHeaders().get("Require-Bundle"); String requiredBundleHeader = (String) bundle.getHeaders().get("Require-Bundle");
if (requiredBundleHeader == null) if (requiredBundleHeader == null) { return; }
{
return;
}
StringTokenizer tokenizer = new ManifestTokenizer(requiredBundleHeader); StringTokenizer tokenizer = new ManifestTokenizer(requiredBundleHeader);
while (tokenizer.hasMoreTokens()) while (tokenizer.hasMoreTokens())
{ {
@ -191,7 +200,8 @@ public class PackageAdminServiceTracker implements ServiceListener
String symbolicName = tokenizer2.nextToken().trim(); String symbolicName = tokenizer2.nextToken().trim();
if (deps.keySet().contains(symbolicName)) if (deps.keySet().contains(symbolicName))
{ {
//was already added. 2 dependencies pointing at the same bundle. // was already added. 2 dependencies pointing at the same
// bundle.
continue; continue;
} }
String versionRange = null; String versionRange = null;
@ -203,7 +213,7 @@ public class PackageAdminServiceTracker implements ServiceListener
{ {
if (next.startsWith("bundle-version=\"") || next.startsWith("bundle-version='")) if (next.startsWith("bundle-version=\"") || next.startsWith("bundle-version='"))
{ {
versionRange = next.substring("bundle-version=\"".length(), next.length()-1); versionRange = next.substring("bundle-version=\"".length(), next.length() - 1);
} }
else else
{ {
@ -215,10 +225,7 @@ public class PackageAdminServiceTracker implements ServiceListener
reexport = true; reexport = true;
} }
} }
if (!reexport && onlyReexport) if (!reexport && onlyReexport) { return; }
{
return;
}
Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange); Bundle[] reqBundles = admin.getBundles(symbolicName, versionRange);
if (reqBundles != null && reqBundles.length != 0) if (reqBundles != null && reqBundles.length != 0)
{ {
@ -233,25 +240,21 @@ public class PackageAdminServiceTracker implements ServiceListener
} }
if (reqBundle == null) if (reqBundle == null)
{ {
//strange? in OSGi with Require-Bundle, // strange? in OSGi with Require-Bundle,
//the dependent bundle is supposed to be active already // the dependent bundle is supposed to be active already
reqBundle = reqBundles[0]; reqBundle = reqBundles[0];
} }
deps.put(reqBundle.getSymbolicName(),reqBundle); deps.put(reqBundle.getSymbolicName(), reqBundle);
collectFragmentsAndRequiredBundles(reqBundle, admin, deps, true); collectFragmentsAndRequiredBundles(reqBundle, admin, deps, true);
} }
} }
} }
private void invokeFragmentActivators(ServiceReference sr) private void invokeFragmentActivators(ServiceReference sr)
{ {
PackageAdmin admin = (PackageAdmin)_context.getService(sr); PackageAdmin admin = (PackageAdmin) _context.getService(sr);
Bundle[] fragments = admin.getFragments(_context.getBundle()); Bundle[] fragments = admin.getFragments(_context.getBundle());
if (fragments == null) if (fragments == null) { return; }
{
return;
}
for (Bundle frag : fragments) for (Bundle frag : fragments)
{ {
// find a convention to look for a class inside the fragment. // find a convention to look for a class inside the fragment.
@ -261,7 +264,7 @@ public class PackageAdminServiceTracker implements ServiceListener
Class<?> c = Class.forName(fragmentActivator); Class<?> c = Class.forName(fragmentActivator);
if (c != null) if (c != null)
{ {
BundleActivator bActivator = (BundleActivator)c.newInstance(); BundleActivator bActivator = (BundleActivator) c.newInstance();
bActivator.start(_context); bActivator.start(_context);
_activatedFragments.add(bActivator); _activatedFragments.add(bActivator);
} }
@ -313,52 +316,58 @@ public class PackageAdminServiceTracker implements ServiceListener
return _startLevel == null ? true : _startLevel.getStartLevel() >= _maxStartLevel; return _startLevel == null ? true : _startLevel.getStartLevel() >= _maxStartLevel;
} }
private static class ManifestTokenizer extends StringTokenizer { private static class ManifestTokenizer extends StringTokenizer
{
public ManifestTokenizer(String header) { public ManifestTokenizer(String header)
{
super(header, ","); super(header, ",");
} }
@Override @Override
public String nextToken() { public String nextToken()
{
String token = super.nextToken(); String token = super.nextToken();
while (hasOpenQuote(token) && hasMoreTokens()) { while (hasOpenQuote(token) && hasMoreTokens())
{
token += "," + super.nextToken(); token += "," + super.nextToken();
} }
return token; return token;
} }
private boolean hasOpenQuote(String token) { private boolean hasOpenQuote(String token)
{
int i = -1; int i = -1;
do { do
int quote = getQuote(token, i+1); {
if (quote < 0) { int quote = getQuote(token, i + 1);
return false; if (quote < 0) { return false; }
}
i = token.indexOf(quote, i+1); i = token.indexOf(quote, i + 1);
i = token.indexOf(quote, i+1); i = token.indexOf(quote, i + 1);
} while (i >= 0); }
while (i >= 0);
return true; return true;
} }
private int getQuote(String token, int offset) { private int getQuote(String token, int offset)
{
int i = token.indexOf('"', offset); int i = token.indexOf('"', offset);
int j = token.indexOf('\'', offset); int j = token.indexOf('\'', offset);
if (i < 0) { if (i < 0)
if (j < 0) { {
if (j < 0)
{
return -1; return -1;
} else { }
else
{
return '\''; return '\'';
} }
} }
if (j < 0) { if (j < 0) { return '"'; }
return '"'; if (i < j) { return '"'; }
}
if (i < j) {
return '"';
}
return '\''; return '\'';
} }

View File

@ -22,28 +22,39 @@ import org.eclipse.jetty.util.component.LifeCycle;
import org.osgi.framework.FrameworkUtil; import org.osgi.framework.FrameworkUtil;
/** /**
* Listens to the start and stop of the NestedConnector to register and unregister the NestedConnector * Listens to the start and stop of the NestedConnector to register and
* with the BridgeServlet. * unregister the NestedConnector with the BridgeServlet.
* <p> * <p>
* All interactions with the BridgeServlet are done via introspection to avoid depending on it directly. * All interactions with the BridgeServlet are done via introspection to avoid
* The BridgeServlet lives in the bootstrap-webapp; not inside equinox. * depending on it directly. The BridgeServlet lives in the bootstrap-webapp;
* not inside equinox.
* </p> * </p>
*/ */
public class NestedConnectorListener extends AbstractLifeCycleListener public class NestedConnectorListener extends AbstractLifeCycleListener
{ {
/** Name of the BridgeServlet class. By default org.eclipse.equinox.servletbridge.BridgeServlet */ /**
* Name of the BridgeServlet class. By default
* org.eclipse.equinox.servletbridge.BridgeServlet
*/
private String bridgeServletClassName = "org.eclipse.equinox.servletbridge.BridgeServlet"; private String bridgeServletClassName = "org.eclipse.equinox.servletbridge.BridgeServlet";
/** Name of the static method on the BridgeServlet class to register the /**
* servlet delegate. By default 'registerServletDelegate' */ * Name of the static method on the BridgeServlet class to register the
* servlet delegate. By default 'registerServletDelegate'
*/
private String registerServletDelegateMethodName = "registerServletDelegate"; private String registerServletDelegateMethodName = "registerServletDelegate";
/** Name of the static method on the BridgeServlet class to register the /**
* servlet delegate. By default 'unregisterServletDelegate' */ * Name of the static method on the BridgeServlet class to register the
* servlet delegate. By default 'unregisterServletDelegate'
*/
private String unregisterServletDelegateMethodName = "unregisterServletDelegate"; private String unregisterServletDelegateMethodName = "unregisterServletDelegate";
/** servlet that wraps this NestedConnector and uses the NestedConnector to service the requests. */ /**
* servlet that wraps this NestedConnector and uses the NestedConnector to
* service the requests.
*/
private NestedConnectorServletDelegate _servletDelegate; private NestedConnectorServletDelegate _servletDelegate;
/** /**
@ -52,8 +63,9 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
private NestedConnector nestedConnector; private NestedConnector nestedConnector;
/** /**
* @param bridgeServletClassName Name of the class that is the BridgeServlet. * @param bridgeServletClassName Name of the class that is the
* By default org.eclipse.equinox.servletbridge.BridgeServlet * BridgeServlet. By default
* org.eclipse.equinox.servletbridge.BridgeServlet
*/ */
public void setBridgeServletClassName(String bridgeServletClassName) public void setBridgeServletClassName(String bridgeServletClassName)
{ {
@ -64,18 +76,20 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
{ {
return this.bridgeServletClassName; return this.bridgeServletClassName;
} }
public String getRegisterServletDelegateMethodName() public String getRegisterServletDelegateMethodName()
{ {
return this.registerServletDelegateMethodName; return this.registerServletDelegateMethodName;
} }
public String getUnregisterServletDelegateMethodName() public String getUnregisterServletDelegateMethodName()
{ {
return this.unregisterServletDelegateMethodName; return this.unregisterServletDelegateMethodName;
} }
/** /**
* @param registerServletDelegateMethodName Name of the static method on the BridgeServlet class * @param registerServletDelegateMethodName Name of the static method on the
* to register the servlet delegate. * BridgeServlet class to register the servlet delegate.
*/ */
public void setRegisterServletDelegateMethodName(String registerServletDelegateMethodName) public void setRegisterServletDelegateMethodName(String registerServletDelegateMethodName)
{ {
@ -83,8 +97,8 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
} }
/** /**
* @param unregisterServletDelegateMethodName Name of the static method on the BridgeServlet class * @param unregisterServletDelegateMethodName Name of the static method on
* to unregister the servlet delegate. * the BridgeServlet class to unregister the servlet delegate.
*/ */
public void setUnregisterServletDelegateMethodName(String unregisterServletDelegateMethodName) public void setUnregisterServletDelegateMethodName(String unregisterServletDelegateMethodName)
{ {
@ -98,6 +112,7 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
{ {
this.nestedConnector = nestedConnector; this.nestedConnector = nestedConnector;
} }
/** /**
* @return The NestedConnector that we are listening to here. * @return The NestedConnector that we are listening to here.
*/ */
@ -115,10 +130,7 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
} }
catch (Exception e) catch (Exception e)
{ {
if (e instanceof RuntimeException) if (e instanceof RuntimeException) { throw (RuntimeException) e; }
{
throw (RuntimeException)e;
}
throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", e); throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", e);
} }
} }
@ -132,10 +144,7 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
} }
catch (Exception e) catch (Exception e)
{ {
if (e instanceof RuntimeException) if (e instanceof RuntimeException) { throw (RuntimeException) e; }
{
throw (RuntimeException)e;
}
throw new RuntimeException("Unable to unregister the servlet delegate into the BridgeServlet.", e); throw new RuntimeException("Unable to unregister the servlet delegate into the BridgeServlet.", e);
} }
} }
@ -148,17 +157,13 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
_servletDelegate = new NestedConnectorServletDelegate(getNestedConnector()); _servletDelegate = new NestedConnectorServletDelegate(getNestedConnector());
try try
{ {
invokeStaticMethod(getBridgeServletClassName(), getRegisterServletDelegateMethodName(), invokeStaticMethod(getBridgeServletClassName(), getRegisterServletDelegateMethodName(), new Class[] { HttpServlet.class }, _servletDelegate);
new Class[] {HttpServlet.class}, _servletDelegate);
} }
catch (Throwable t) catch (Throwable t)
{ {
_servletDelegate.destroy(); _servletDelegate.destroy();
_servletDelegate = null; _servletDelegate = null;
if (t instanceof Exception) if (t instanceof Exception) { throw (Exception) t; }
{
throw (Exception)t;
}
throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", t); throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", t);
} }
} }
@ -172,15 +177,11 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
{ {
try try
{ {
invokeStaticMethod(getBridgeServletClassName(), getUnregisterServletDelegateMethodName(), invokeStaticMethod(getBridgeServletClassName(), getUnregisterServletDelegateMethodName(), new Class[] { HttpServlet.class }, _servletDelegate);
new Class[] {HttpServlet.class}, _servletDelegate);
} }
catch (Throwable t) catch (Throwable t)
{ {
if (t instanceof Exception) if (t instanceof Exception) { throw (Exception) t; }
{
throw (Exception)t;
}
throw new RuntimeException("Unable to unregister the servlet delegate from the BridgeServlet.", t); throw new RuntimeException("Unable to unregister the servlet delegate from the BridgeServlet.", t);
} }
finally finally
@ -198,8 +199,7 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
* @param argType * @param argType
* @throws Exception * @throws Exception
*/ */
private static void invokeStaticMethod(String clName, String methName, Class[] argType, Object...args) private static void invokeStaticMethod(String clName, String methName, Class[] argType, Object... args) throws Exception
throws Exception
{ {
Method m = getMethod(clName, methName, argType); Method m = getMethod(clName, methName, argType);
m.invoke(null, args); m.invoke(null, args);
@ -207,20 +207,19 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
/** /**
* *
* @param clName Class that belongs to the parent classloader of the OSGi framework. * @param clName Class that belongs to the parent classloader of the OSGi
* framework.
* @param methName Name of the method to find. * @param methName Name of the method to find.
* @param argType Argument types of the method to find. * @param argType Argument types of the method to find.
* @throws Exception * @throws Exception
*/ */
private static Method getMethod(String clName, String methName, Class... argType) private static Method getMethod(String clName, String methName, Class... argType) throws Exception
throws Exception
{ {
Class bridgeServletClass = FrameworkUtil.class.getClassLoader() Class bridgeServletClass = FrameworkUtil.class.getClassLoader().loadClass(clName);
.loadClass(clName);
return getMethod(bridgeServletClass, methName, argType); return getMethod(bridgeServletClass, methName, argType);
} }
private static Method getMethod(Class cl, String methName, Class... argType)
throws Exception private static Method getMethod(Class cl, String methName, Class... argType) throws Exception
{ {
Method meth = null; Method meth = null;
try try
@ -238,14 +237,19 @@ public class NestedConnectorListener extends AbstractLifeCycleListener
for (Class p : m.getParameterTypes()) for (Class p : m.getParameterTypes())
{ {
Class ap = argType[i]; Class ap = argType[i];
if (p.getName().equals(ap.getName()) if (p.getName().equals(ap.getName()) && !p.equals(ap)) { throw new IllegalStateException(
&& !p.equals(ap)) "The method \"" + m.toGenericString()
{ + "\" was found. but the parameter class "
throw new IllegalStateException("The method \"" + m.toGenericString() + + p.getName()
"\" was found. but the parameter class " + p.getName() + " is not the same " + + " is not the same "
" inside OSGi classloader (" + ap.getClassLoader() + ") and inside the " + + " inside OSGi classloader ("
cl.getName() + " classloader (" + p.getClassLoader() + ")." + + ap.getClassLoader()
" Are the ExtensionBundles correctly defined?"); + ") and inside the "
+ cl.getName()
+ " classloader ("
+ p.getClassLoader()
+ ")."
+ " Are the ExtensionBundles correctly defined?");
} }
} }

View File

@ -37,8 +37,7 @@ public class NestedConnectorServletDelegate extends HttpServlet
} }
@Override @Override
public void service(ServletRequest req, ServletResponse res) public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
throws ServletException, IOException
{ {
_nestedConnector.service(req, res); _nestedConnector.service(req, res);
} }