Issue #213
This commit is contained in:
parent
2f1d2dac72
commit
37fa778ea0
|
@ -27,11 +27,15 @@ import java.util.Map;
|
|||
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.util.tracker.BundleTracker;
|
||||
|
||||
/**
|
||||
* BundleContextProvider
|
||||
|
@ -47,6 +51,62 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu
|
|||
private Map<Bundle, List<App>> _bundleMap = new HashMap<Bundle, List<App>>();
|
||||
|
||||
private ServiceRegistration _serviceRegForBundles;
|
||||
|
||||
private BundleTracker _tracker;
|
||||
|
||||
|
||||
public class ContextBundleTracker extends BundleTracker
|
||||
{
|
||||
protected String _managedServerName;
|
||||
|
||||
public ContextBundleTracker (BundleContext bundleContext, String managedServerName)
|
||||
{
|
||||
super (bundleContext, Bundle.ACTIVE | Bundle.STOPPING,null);
|
||||
_managedServerName = managedServerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.BundleTracker#addingBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent)
|
||||
*/
|
||||
@Override
|
||||
public Object addingBundle(Bundle bundle, BundleEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME))
|
||||
|| (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName))))
|
||||
{
|
||||
if (bundleAdded (bundle))
|
||||
return bundle;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.BundleTracker#removedBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void removedBundle(Bundle bundle, BundleEvent event, Object object)
|
||||
{
|
||||
try
|
||||
{
|
||||
bundleRemoved(bundle);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public BundleContextProvider(ServerInstanceWrapper wrapper)
|
||||
|
@ -59,6 +119,10 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu
|
|||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
//Track bundles that are ContextHandlers that should be deployed
|
||||
_tracker = new ContextBundleTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName());
|
||||
_tracker.open();
|
||||
|
||||
//register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to
|
||||
Dictionary<String,String> properties = new Hashtable<String,String>();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
|
||||
|
@ -70,6 +134,8 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_tracker.close();
|
||||
|
||||
//unregister ourselves
|
||||
if (_serviceRegForBundles != null)
|
||||
{
|
||||
|
|
|
@ -26,11 +26,15 @@ import java.util.Map;
|
|||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.osgi.boot.utils.Util;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.util.tracker.BundleTracker;
|
||||
|
||||
/**
|
||||
* BundleWebAppProvider
|
||||
|
@ -48,6 +52,62 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
|
|||
|
||||
private ServiceRegistration _serviceRegForBundles;
|
||||
|
||||
private WebAppTracker _webappTracker;
|
||||
|
||||
|
||||
public class WebAppTracker extends BundleTracker
|
||||
{
|
||||
protected String _managedServerName;
|
||||
|
||||
public WebAppTracker (BundleContext bundleContext, String managedServerName)
|
||||
{
|
||||
super (bundleContext, Bundle.ACTIVE | Bundle.STOPPING,null);
|
||||
_managedServerName = managedServerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.BundleTracker#addingBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent)
|
||||
*/
|
||||
@Override
|
||||
public Object addingBundle(Bundle bundle, BundleEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME))
|
||||
|| (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName))))
|
||||
{
|
||||
if (bundleAdded (bundle))
|
||||
return bundle;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.BundleTracker#removedBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void removedBundle(Bundle bundle, BundleEvent event, Object object)
|
||||
{
|
||||
try
|
||||
{
|
||||
bundleRemoved(bundle);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public BundleWebAppProvider (ServerInstanceWrapper wrapper)
|
||||
|
@ -61,6 +121,8 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
|
|||
*/
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
_webappTracker = new WebAppTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName());
|
||||
_webappTracker.open();
|
||||
//register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to
|
||||
Dictionary<String,String> properties = new Hashtable<String,String>();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
|
||||
|
@ -75,6 +137,8 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
_webappTracker.close();
|
||||
|
||||
//unregister ourselves
|
||||
if (_serviceRegForBundles != null)
|
||||
{
|
||||
|
|
|
@ -20,18 +20,13 @@ package org.eclipse.jetty.osgi.boot;
|
|||
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleWatcher;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.ServiceWatcher;
|
||||
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.util.tracker.BundleTracker;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
|
@ -55,14 +50,10 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
}
|
||||
|
||||
private ServiceRegistration _registeredServer;
|
||||
|
||||
private ServiceTracker _contextHandlerTracker;
|
||||
|
||||
private PackageAdminServiceTracker _packageAdminServiceTracker;
|
||||
|
||||
private BundleTracker _webBundleTracker;
|
||||
|
||||
private JettyServerServiceTracker _jettyServerServiceTracker;
|
||||
private ServiceTracker _jettyServerServiceTracker;
|
||||
|
||||
|
||||
|
||||
|
@ -77,7 +68,6 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
*/
|
||||
public void start(final BundleContext context) throws Exception
|
||||
{
|
||||
try {
|
||||
INSTANCE = this;
|
||||
|
||||
// track other bundles and fragments attached to this bundle that we
|
||||
|
@ -85,27 +75,15 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
_packageAdminServiceTracker = new PackageAdminServiceTracker(context);
|
||||
|
||||
// track jetty Server instances that we should support as deployment targets
|
||||
_jettyServerServiceTracker = new JettyServerServiceTracker();
|
||||
context.addServiceListener(_jettyServerServiceTracker, "(objectclass=" + Server.class.getName() + ")");
|
||||
|
||||
_jettyServerServiceTracker = new ServiceTracker(context, context.createFilter("(objectclass=" + Server.class.getName() + ")"), new JettyServerServiceTracker());
|
||||
_jettyServerServiceTracker.open();
|
||||
|
||||
// Create a default jetty instance right now.
|
||||
Server defaultServer = DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context);
|
||||
|
||||
// track ContextHandler class instances and deploy them to one of the known Servers
|
||||
_contextHandlerTracker = new ServiceTracker(context, context.createFilter("(objectclass=" + ContextHandler.class.getName() + ")"), new ServiceWatcher());
|
||||
_contextHandlerTracker.open();
|
||||
|
||||
//Create a bundle tracker to help deploy webapps and ContextHandlers
|
||||
BundleWatcher bundleTrackerCustomizer = new BundleWatcher();
|
||||
bundleTrackerCustomizer.setWaitForDefaultServer(defaultServer != null);
|
||||
_webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, bundleTrackerCustomizer);
|
||||
bundleTrackerCustomizer.setBundleTracker(_webBundleTracker);
|
||||
bundleTrackerCustomizer.open();
|
||||
} catch (Exception e) { e.printStackTrace();}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Stop the activator.
|
||||
|
@ -117,20 +95,9 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
{
|
||||
try
|
||||
{
|
||||
if (_webBundleTracker != null)
|
||||
{
|
||||
_webBundleTracker.close();
|
||||
_webBundleTracker = null;
|
||||
}
|
||||
if (_contextHandlerTracker != null)
|
||||
{
|
||||
_contextHandlerTracker.close();
|
||||
_contextHandlerTracker = null;
|
||||
}
|
||||
if (_jettyServerServiceTracker != null)
|
||||
{
|
||||
_jettyServerServiceTracker.stop();
|
||||
context.removeServiceListener(_jettyServerServiceTracker);
|
||||
_jettyServerServiceTracker.close();
|
||||
_jettyServerServiceTracker = null;
|
||||
}
|
||||
if (_packageAdminServiceTracker != null)
|
||||
|
|
|
@ -27,14 +27,19 @@ import org.eclipse.jetty.deploy.App;
|
|||
import org.eclipse.jetty.deploy.AppProvider;
|
||||
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.osgi.boot.utils.Util;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.Constants;
|
||||
import org.osgi.framework.Filter;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
* ServiceContextProvider
|
||||
|
@ -51,6 +56,55 @@ public class ServiceContextProvider extends AbstractContextProvider implements S
|
|||
|
||||
private ServiceRegistration _serviceRegForServices;
|
||||
|
||||
ServiceTracker _tracker;
|
||||
|
||||
|
||||
/**
|
||||
* ContextTracker
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ContextTracker extends ServiceTracker
|
||||
{
|
||||
|
||||
public ContextTracker (BundleContext bundleContext, Filter filter)
|
||||
{
|
||||
super(bundleContext, filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
|
||||
*/
|
||||
@Override
|
||||
public Object addingService(ServiceReference reference)
|
||||
{
|
||||
ContextHandler h = (ContextHandler)context.getService(reference);
|
||||
serviceAdded (reference, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void modifiedService(ServiceReference reference, Object service)
|
||||
{
|
||||
removedService(reference,service);
|
||||
addingService(reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void removedService(ServiceReference reference, Object service)
|
||||
{
|
||||
context.ungetService(reference);
|
||||
serviceRemoved(reference, (ContextHandler)service);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ServiceApp
|
||||
|
@ -162,6 +216,15 @@ public class ServiceContextProvider extends AbstractContextProvider implements S
|
|||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
|
||||
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
|
||||
|
||||
//Start a tracker to find webapps that are osgi services that are targetted to my server name
|
||||
_tracker = new ContextTracker (bundleContext,
|
||||
Util.createFilter(bundleContext, ContextHandler.class.getName(), getServerInstanceWrapper().getManagedServerName()));
|
||||
_tracker.open();
|
||||
|
||||
|
||||
//register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to
|
||||
Dictionary<String,String> properties = new Hashtable<String,String>();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
|
||||
|
@ -175,6 +238,9 @@ public class ServiceContextProvider extends AbstractContextProvider implements S
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
if (_tracker != null)
|
||||
_tracker.close();
|
||||
|
||||
//unregister ourselves
|
||||
if (_serviceRegForServices != null)
|
||||
{
|
||||
|
|
|
@ -27,14 +27,19 @@ import org.eclipse.jetty.deploy.App;
|
|||
import org.eclipse.jetty.deploy.AppProvider;
|
||||
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.osgi.boot.utils.Util;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.Filter;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
* ServiceWebAppProvider
|
||||
|
@ -52,6 +57,58 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser
|
|||
|
||||
private ServiceRegistration _serviceRegForServices;
|
||||
|
||||
private ServiceTracker webappTracker;
|
||||
|
||||
|
||||
/**
|
||||
* WebAppTracker
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class WebAppTracker extends ServiceTracker
|
||||
{
|
||||
/**
|
||||
* @param bundleContext the osgi context
|
||||
* @param filter the osgi filter for the tracker
|
||||
*/
|
||||
public WebAppTracker (BundleContext bundleContext, Filter filter)
|
||||
{
|
||||
super(bundleContext, filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
|
||||
*/
|
||||
@Override
|
||||
public Object addingService(ServiceReference reference)
|
||||
{
|
||||
WebAppContext wac = (WebAppContext)context.getService(reference);
|
||||
serviceAdded (reference, wac);
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void modifiedService(ServiceReference reference, Object service)
|
||||
{
|
||||
removedService(reference,service);
|
||||
addingService(reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void removedService(ServiceReference reference, Object service)
|
||||
{
|
||||
serviceRemoved(reference, (WebAppContext)service);
|
||||
context.ungetService(reference);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ServiceApp
|
||||
*
|
||||
|
@ -207,6 +264,13 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser
|
|||
*/
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
|
||||
|
||||
//Start a tracker to find webapps that are osgi services that are targetted to my server name
|
||||
webappTracker = new WebAppTracker (bundleContext,
|
||||
Util.createFilter(bundleContext, WebAppContext.class.getName(), getServerInstanceWrapper().getManagedServerName()));
|
||||
webappTracker.open();
|
||||
|
||||
//register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to
|
||||
Dictionary<String,String> properties = new Hashtable<String,String>();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
|
||||
|
@ -223,6 +287,8 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
webappTracker.close();
|
||||
|
||||
//unregister ourselves
|
||||
if (_serviceRegForServices != null)
|
||||
{
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.osgi.boot.internal.serverfactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
|
@ -27,9 +25,8 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.util.tracker.ServiceTrackerCustomizer;
|
||||
|
||||
/**
|
||||
* JettyServerServiceTracker
|
||||
|
@ -38,116 +35,71 @@ import org.osgi.framework.ServiceReference;
|
|||
* webapps or ContextHandlers discovered from the OSGi environment.
|
||||
*
|
||||
*/
|
||||
public class JettyServerServiceTracker implements ServiceListener
|
||||
public class JettyServerServiceTracker implements ServiceTrackerCustomizer
|
||||
{
|
||||
private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName());
|
||||
|
||||
|
||||
/** The context-handler to deactivate indexed by ServerInstanceWrapper */
|
||||
private Map<ServiceReference, ServerInstanceWrapper> _indexByServiceReference = new HashMap<ServiceReference, ServerInstanceWrapper>();
|
||||
|
||||
/**
|
||||
* Stops each one of the registered servers.
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
|
||||
*/
|
||||
public void stop()
|
||||
@Override
|
||||
public Object addingService(ServiceReference sr)
|
||||
{
|
||||
for (ServerInstanceWrapper wrapper : _indexByServiceReference.values())
|
||||
Bundle contributor = sr.getBundle();
|
||||
Server server = (Server) contributor.getBundleContext().getService(sr);
|
||||
String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); }
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Adding Server {}", name);
|
||||
ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
|
||||
Properties props = new Properties();
|
||||
for (String key : sr.getPropertyKeys())
|
||||
{
|
||||
Object value = sr.getProperty(key);
|
||||
props.put(key, value);
|
||||
}
|
||||
try
|
||||
{
|
||||
wrapper.start(server, props);
|
||||
LOG.info("Started Server {}", name);
|
||||
return wrapper;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
return sr.getBundle().getBundleContext().getService(sr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void modifiedService(ServiceReference reference, Object service)
|
||||
{
|
||||
removedService(reference, service);
|
||||
addingService(reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void removedService(ServiceReference reference, Object service)
|
||||
{
|
||||
if (service instanceof ServerInstanceWrapper)
|
||||
{
|
||||
try
|
||||
{
|
||||
ServerInstanceWrapper wrapper = (ServerInstanceWrapper)service;
|
||||
wrapper.stop();
|
||||
LOG.info("Stopped Server {}",wrapper.getManagedServerName());
|
||||
}
|
||||
catch (Throwable t)
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(t);
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives notification that a service has had a lifecycle change.
|
||||
*
|
||||
* @param ev The <code>ServiceEvent</code> object.
|
||||
*/
|
||||
public void serviceChanged(ServiceEvent ev)
|
||||
{
|
||||
ServiceReference sr = ev.getServiceReference();
|
||||
switch (ev.getType())
|
||||
{
|
||||
case ServiceEvent.MODIFIED:
|
||||
case ServiceEvent.UNREGISTERING:
|
||||
{
|
||||
ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
|
||||
if (instance != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
instance.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.getType() == ServiceEvent.UNREGISTERING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// modified, meaning: we reload it. now that we stopped it;
|
||||
// we can register it.
|
||||
}
|
||||
}
|
||||
case ServiceEvent.REGISTERED:
|
||||
{
|
||||
try
|
||||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
Server server = (Server) contributor.getBundleContext().getService(sr);
|
||||
ServerInstanceWrapper wrapper = registerInIndex(server, sr);
|
||||
Properties props = new Properties();
|
||||
for (String key : sr.getPropertyKeys())
|
||||
{
|
||||
Object value = sr.getProperty(key);
|
||||
props.put(key, value);
|
||||
}
|
||||
wrapper.start(server, props);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr)
|
||||
{
|
||||
String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); }
|
||||
ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
|
||||
_indexByServiceReference.put(sr, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ContextHandler to stop.
|
||||
*
|
||||
* @param reg
|
||||
* @return the ContextHandler to stop.
|
||||
*/
|
||||
private ServerInstanceWrapper unregisterInIndex(ServiceReference sr)
|
||||
{
|
||||
ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
|
||||
if (handler == null)
|
||||
{
|
||||
LOG.warn("Unknown Jetty Server ServiceReference: ", sr);
|
||||
return null;
|
||||
}
|
||||
|
||||
return handler;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,307 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.BundleProvider;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.util.tracker.BundleTracker;
|
||||
import org.osgi.util.tracker.BundleTrackerCustomizer;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
* BundleWatcher
|
||||
*
|
||||
* Tracks the installation and removal of Bundles in the OSGi environment. Any bundles
|
||||
* that are added are passed to the set of Jetty DeploymentManager providers to see if
|
||||
* the bundle should be deployed as a webapp or ContextHandler into Jetty.
|
||||
*/
|
||||
public class BundleWatcher implements BundleTrackerCustomizer
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(BundleWatcher.class);
|
||||
|
||||
public static final Collection<TldBundleDiscoverer> JSP_REGISTRATION_HELPERS = new ArrayList<TldBundleDiscoverer>();
|
||||
|
||||
|
||||
public static final String FILTER = "(objectclass=" + BundleProvider.class.getName() + ")";
|
||||
private ServiceTracker _serviceTracker;
|
||||
private BundleTracker _bundleTracker;
|
||||
private boolean _waitForDefaultServer = true;
|
||||
private boolean _defaultServerReady = false;
|
||||
private Bundle _bundle = null;
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public BundleWatcher() throws Exception
|
||||
{
|
||||
_bundle = FrameworkUtil.getBundle(this.getClass());
|
||||
//Track all BundleProviders (Jetty DeploymentManager Providers that can deploy bundles)
|
||||
_serviceTracker = new ServiceTracker(_bundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null);
|
||||
_serviceTracker.open();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isWaitForDefaultServer()
|
||||
{
|
||||
return _waitForDefaultServer;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setWaitForDefaultServer(boolean waitForDefaultServer)
|
||||
{
|
||||
_waitForDefaultServer = waitForDefaultServer;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setBundleTracker (BundleTracker bundleTracker)
|
||||
{
|
||||
_bundleTracker = bundleTracker;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void open () throws Exception
|
||||
{
|
||||
if (_waitForDefaultServer && !_defaultServerReady)
|
||||
{
|
||||
String filter = "(&(objectclass=" + BundleProvider.class.getName() + ")"+
|
||||
"("+OSGiServerConstants.MANAGED_JETTY_SERVER_NAME+"="+OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME+"))";
|
||||
|
||||
ServiceTracker defaultServerTracker = new ServiceTracker(_bundle.getBundleContext(),
|
||||
FrameworkUtil.createFilter(filter),null)
|
||||
{
|
||||
public Object addingService(ServiceReference reference)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object object = super.addingService(reference);
|
||||
LOG.debug("Default Jetty Server registered {}", reference);
|
||||
_defaultServerReady = true;
|
||||
openBundleTracker();
|
||||
return object;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
defaultServerTracker.open();
|
||||
}
|
||||
else
|
||||
openBundleTracker();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Map<ServiceReference, BundleProvider> getDeployers(String managedServerName)
|
||||
{
|
||||
if (managedServerName == null)
|
||||
managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
|
||||
|
||||
Map<ServiceReference, BundleProvider> candidates = new HashMap<ServiceReference, BundleProvider>();
|
||||
|
||||
ServiceReference[] references = _serviceTracker.getServiceReferences();
|
||||
if (references != null)
|
||||
{
|
||||
for (ServiceReference ref:references)
|
||||
{
|
||||
String name = (String)ref.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (managedServerName.equalsIgnoreCase(name))
|
||||
{
|
||||
BundleProvider candidate = (BundleProvider)_serviceTracker.getService(ref);
|
||||
if (candidate != null)
|
||||
candidates.put(ref, candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* A bundle is being added to the <code>BundleTracker</code>.
|
||||
*
|
||||
* <p>
|
||||
* This method is called before a bundle which matched the search parameters
|
||||
* of the <code>BundleTracker</code> is added to the
|
||||
* <code>BundleTracker</code>. This method should return the object to be
|
||||
* tracked for the specified <code>Bundle</code>. The returned object is
|
||||
* stored in the <code>BundleTracker</code> and is available from the
|
||||
* {@link BundleTracker#getObject(Bundle) getObject} method.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> being added to the
|
||||
* <code>BundleTracker</code>.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event
|
||||
* associated with the call to this method.
|
||||
* @return The object to be tracked for the specified <code>Bundle</code>
|
||||
* object or <code>null</code> if the specified <code>Bundle</code>
|
||||
* object should not be tracked.
|
||||
*/
|
||||
public Object addingBundle(Bundle bundle, BundleEvent event)
|
||||
{
|
||||
if (bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
register(bundle);
|
||||
}
|
||||
else if (bundle.getState() == Bundle.STOPPING)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we should not be called in that state as
|
||||
// we are registered only for ACTIVE and STOPPING
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* A bundle tracked by the <code>BundleTracker</code> has been modified.
|
||||
*
|
||||
* <p>
|
||||
* This method is called when a bundle being tracked by the
|
||||
* <code>BundleTracker</code> has had its state modified.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> whose state has been modified.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event
|
||||
* associated with the call to this method.
|
||||
* @param object The tracked object for the specified bundle.
|
||||
*/
|
||||
public void modifiedBundle(Bundle bundle, BundleEvent event, Object object)
|
||||
{
|
||||
if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
if (bundle.getState() == Bundle.ACTIVE)
|
||||
{
|
||||
register(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* A bundle tracked by the <code>BundleTracker</code> has been removed.
|
||||
*
|
||||
* <p>
|
||||
* This method is called after a bundle is no longer being tracked by the
|
||||
* <code>BundleTracker</code>.
|
||||
*
|
||||
* @param bundle The <code>Bundle</code> that has been removed.
|
||||
* @param event The bundle event which caused this customizer method to be
|
||||
* called or <code>null</code> if there is no bundle event
|
||||
* associated with the call to this method.
|
||||
* @param object The tracked object for the specified bundle.
|
||||
*/
|
||||
public void removedBundle(Bundle bundle, BundleEvent event, Object object)
|
||||
{
|
||||
unregister(bundle);
|
||||
}
|
||||
|
||||
|
||||
protected void openBundleTracker()
|
||||
{
|
||||
_bundleTracker.open();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param bundle
|
||||
* @return true if this bundle can be deployed into Jetty
|
||||
*/
|
||||
private boolean register(Bundle bundle)
|
||||
{
|
||||
if (bundle == null)
|
||||
return false;
|
||||
|
||||
//It might be a bundle that is deployable by Jetty.
|
||||
//Use any named Server instance provided, defaulting to the default Server instance if none supplied
|
||||
boolean deployed = false;
|
||||
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
Map<ServiceReference, BundleProvider> candidates = getDeployers(serverName);
|
||||
if (candidates != null)
|
||||
{
|
||||
Iterator<Entry<ServiceReference, BundleProvider>> itor = candidates.entrySet().iterator();
|
||||
while (!deployed && itor.hasNext())
|
||||
{
|
||||
Entry<ServiceReference, BundleProvider> e = itor.next();
|
||||
try
|
||||
{
|
||||
deployed = e.getValue().bundleAdded(bundle);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.warn("Error deploying bundle for jetty context", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return deployed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param bundle
|
||||
*/
|
||||
private void unregister(Bundle bundle)
|
||||
{
|
||||
boolean undeployed = false;
|
||||
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
Map<ServiceReference, BundleProvider> candidates = getDeployers(serverName);
|
||||
if (candidates != null)
|
||||
{
|
||||
Iterator<Entry<ServiceReference, BundleProvider>> itor = candidates.entrySet().iterator();
|
||||
while (!undeployed && itor.hasNext())
|
||||
{
|
||||
Entry<ServiceReference, BundleProvider> e = itor.next();
|
||||
try
|
||||
{
|
||||
undeployed = e.getValue().bundleRemoved(bundle);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.warn("Error undeploying Bundle representing jetty deployable ", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,223 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
|
||||
import org.eclipse.jetty.osgi.boot.ServiceProvider;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
import org.osgi.util.tracker.ServiceTrackerCustomizer;
|
||||
|
||||
/**
|
||||
* ServiceWatcher
|
||||
*
|
||||
* When a {@link ContextHandler} is activated as an osgi service we find a jetty deployer
|
||||
* for it. The ContextHandler could be either a WebAppContext or any other derivative of
|
||||
* ContextHandler.
|
||||
*
|
||||
* ContextHandlers and WebApps can also be deployed into jetty without creating them as
|
||||
* osgi services. Instead, they can be deployed via manifest headers inside bundles. See
|
||||
* {@link BundleWatcher}.
|
||||
*/
|
||||
public class ServiceWatcher implements ServiceTrackerCustomizer
|
||||
{
|
||||
private static Logger LOG = Log.getLogger(ServiceWatcher.class);
|
||||
|
||||
public static final String FILTER = "(objectclass=" + ServiceProvider.class.getName() + ")";
|
||||
|
||||
//track all instances of deployers of webapps as bundles
|
||||
ServiceTracker _serviceTracker;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public ServiceWatcher() throws Exception
|
||||
{
|
||||
//track all instances of deployers of webapps
|
||||
Bundle myBundle = FrameworkUtil.getBundle(this.getClass());
|
||||
_serviceTracker = new ServiceTracker(myBundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null);
|
||||
_serviceTracker.open();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Map<ServiceReference, ServiceProvider> getDeployers(String managedServerName)
|
||||
{
|
||||
if (managedServerName == null)
|
||||
managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
|
||||
|
||||
Map<ServiceReference, ServiceProvider> candidates = new HashMap<ServiceReference, ServiceProvider>();
|
||||
|
||||
ServiceReference[] references = _serviceTracker.getServiceReferences();
|
||||
if (references != null)
|
||||
{
|
||||
for (ServiceReference ref:references)
|
||||
{
|
||||
String name = (String)ref.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (managedServerName.equalsIgnoreCase(name))
|
||||
{
|
||||
ServiceProvider candidate = (ServiceProvider)_serviceTracker.getService(ref);
|
||||
if (candidate != null)
|
||||
candidates.put(ref, candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* A Service that is a ContextHandler is detected.
|
||||
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
|
||||
*/
|
||||
@Override
|
||||
public Object addingService(ServiceReference reference)
|
||||
{
|
||||
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
|
||||
ContextHandler contextHandler = (ContextHandler) context.getService(reference);
|
||||
return addService(context, contextHandler, reference);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* A Service that is a ContextHandler has been modified. We
|
||||
* undeploy and then redeploy the ContextHandler.
|
||||
*
|
||||
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void modifiedService(ServiceReference reference, Object service)
|
||||
{
|
||||
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
|
||||
ContextHandler contextHandler = (ContextHandler) context.getService(reference);
|
||||
removeService (context, contextHandler, reference);
|
||||
addService (context, contextHandler, reference);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* A Service that is a ContextHandler is being removed.
|
||||
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void removedService(ServiceReference reference, Object service)
|
||||
{
|
||||
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
|
||||
ContextHandler contextHandler = (ContextHandler) context.getService(reference);
|
||||
removeService (context, contextHandler, reference);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Deploy ContextHandler that is a Service.
|
||||
* @param context the bundle context
|
||||
* @param contextHandler the context handler
|
||||
* @param reference the service reference
|
||||
* @return the object added
|
||||
*/
|
||||
public Object addService (BundleContext context, ContextHandler contextHandler, ServiceReference reference)
|
||||
{
|
||||
if (contextHandler.getServer() != null)
|
||||
{
|
||||
// is configured elsewhere.
|
||||
return context.getService(reference);
|
||||
}
|
||||
String watermark = (String)reference.getProperty(OSGiWebappConstants.WATERMARK);
|
||||
if (watermark != null && !"".equals(watermark))
|
||||
return context.getService(reference); //one of our deployers just registered the context as an OSGi service, so we can ignore it
|
||||
|
||||
//Get a jetty deployer targetted to the named server instance, or the default one if not named
|
||||
String serverName = (String)reference.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
Map<ServiceReference, ServiceProvider> candidates = getDeployers(serverName);
|
||||
if (candidates != null)
|
||||
{
|
||||
boolean added = false;
|
||||
Iterator<Entry<ServiceReference, ServiceProvider>> itor = candidates.entrySet().iterator();
|
||||
while (!added && itor.hasNext())
|
||||
{
|
||||
Entry<ServiceReference, ServiceProvider> e = itor.next();
|
||||
try
|
||||
{
|
||||
added = e.getValue().serviceAdded(reference, contextHandler);
|
||||
if (added && LOG.isDebugEnabled())
|
||||
LOG.debug("Provider "+e.getValue()+" deployed "+contextHandler);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.warn("Error deploying service representing jetty context", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
return context.getService(reference);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Undeploy a ContextHandler that is a Service.
|
||||
* @param context the bundle context
|
||||
* @param contextHandler the context handler
|
||||
* @param reference the service reference
|
||||
*/
|
||||
public void removeService (BundleContext context, ContextHandler contextHandler, ServiceReference reference)
|
||||
{
|
||||
//Get a jetty deployer targetted to the named server instance, or the default one if not named
|
||||
//The individual deployer will decide if it can remove the context or not
|
||||
String serverName = (String)reference.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
Map<ServiceReference, ServiceProvider> candidates = getDeployers(serverName);
|
||||
if (candidates != null)
|
||||
{
|
||||
boolean removed = false;
|
||||
Iterator<Entry<ServiceReference, ServiceProvider>> itor = candidates.entrySet().iterator();
|
||||
while (!removed && itor.hasNext())
|
||||
{
|
||||
Entry<ServiceReference, ServiceProvider> e = itor.next();
|
||||
try
|
||||
{
|
||||
removed = e.getValue().serviceRemoved(reference, contextHandler);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.warn("Error undeploying service representing jetty context ", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,13 +19,18 @@
|
|||
|
||||
package org.eclipse.jetty.osgi.boot.utils;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Dictionary;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.Filter;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
|
||||
/**
|
||||
* Various useful functions utility methods for OSGi wide use.
|
||||
*/
|
||||
|
@ -34,6 +39,31 @@ public class Util
|
|||
public static final String DEFAULT_DELIMS = ",;";
|
||||
|
||||
|
||||
/**
|
||||
* Create an osgi filter for the given classname and server name.
|
||||
*
|
||||
* @param bundleContext
|
||||
* @param classname the class to match on the filter
|
||||
* @param managedServerName the name of the jetty server instance
|
||||
* @return a new filter
|
||||
*
|
||||
* @throws InvalidSyntaxException
|
||||
*/
|
||||
public static Filter createFilter (BundleContext bundleContext, String classname, String managedServerName) throws InvalidSyntaxException
|
||||
{
|
||||
if (StringUtil.isBlank(managedServerName) || managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME))
|
||||
{
|
||||
return bundleContext.createFilter("(&(objectclass=" + classname
|
||||
+ ")(|(managedServerName="+managedServerName
|
||||
+")(!(managedServerName=*))))");
|
||||
}
|
||||
else
|
||||
{
|
||||
return bundleContext.createFilter("(&(objectclass=" + classname+ ")(managedServerName="+managedServerName+"))");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a manifest header.
|
||||
*
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<module>test-jetty-osgi-webapp</module>
|
||||
<module>test-jetty-osgi-context</module>
|
||||
<module>test-jetty-osgi-fragment</module>
|
||||
<module>test-jetty-osgi-server</module>
|
||||
<module>jetty-osgi-alpn</module>
|
||||
<module>test-jetty-osgi</module>
|
||||
</modules>
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.servlet.ServletContextListener;
|
|||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
* Bootstrap a ContextHandler
|
||||
|
@ -36,6 +37,7 @@ import org.osgi.framework.BundleContext;
|
|||
public class Activator implements BundleActivator
|
||||
{
|
||||
|
||||
private ServiceRegistration _sr;
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
|
@ -48,20 +50,20 @@ public class Activator implements BundleActivator
|
|||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce)
|
||||
{
|
||||
// System.err.println("Context is initialized");
|
||||
//System.err.println("Context is initialized");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce)
|
||||
{
|
||||
// System.err.println("CONTEXT IS DESTROYED!");
|
||||
//System.err.println("CONTEXT IS DESTROYED!");
|
||||
}
|
||||
|
||||
});
|
||||
Dictionary props = new Hashtable();
|
||||
props.put("contextPath","/acme");
|
||||
props.put("Jetty-ContextFilePath", "acme.xml");
|
||||
context.registerService(ContextHandler.class.getName(),ch,props);
|
||||
_sr = context.registerService(ContextHandler.class.getName(),ch,props);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,5 +74,6 @@ public class Activator implements BundleActivator
|
|||
*/
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
_sr.unregister();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>9.4.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-jetty-osgi-server</artifactId>
|
||||
<name>Jetty :: OSGi :: Server</name>
|
||||
<description>Test Jetty OSGi bundle with a Server</description>
|
||||
<url>http://www.eclipse.org/jetty</url>
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.testserver</bundle-symbolic-name>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi.services</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-schemas</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- DO NOT DEPLOY (or Release) -->
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>${bundle-symbolic-name}</Bundle-SymbolicName>
|
||||
<Bundle-Name>Jetty OSGi Test Server</Bundle-Name>
|
||||
<Bundle-Activator>com.acme.osgi.Activator</Bundle-Activator>
|
||||
<Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
|
||||
<!-- disable the uses directive: jetty will accommodate pretty much any versions
|
||||
of the packages it uses; no need to reflect some tight dependency determined at
|
||||
compilation time. -->
|
||||
<_nouses>true</_nouses>
|
||||
<Import-Package>
|
||||
javax.servlet;version="[3.1,3.2)",
|
||||
javax.servlet.resources;version="[3.1,3.2)",
|
||||
org.osgi.framework,
|
||||
org.osgi.service.cm;version="1.2.0",
|
||||
org.osgi.service.packageadmin,
|
||||
org.osgi.service.startlevel;version="1.0.o",
|
||||
org.osgi.service.url;version="1.0.0",
|
||||
org.osgi.util.tracker;version="1.3.0",
|
||||
org.slf4j;resolution:=optional,
|
||||
org.slf4j.spi;resolution:=optional,
|
||||
org.slf4j.helpers;resolution:=optional,
|
||||
org.xml.sax,
|
||||
org.xml.sax.helpers,
|
||||
*
|
||||
</Import-Package>
|
||||
<DynamicImport-Package>org.eclipse.jetty.*;version="[9.1,10.0)"</DynamicImport-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package com.acme.osgi;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
* Bootstrap a Server
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Activator implements BundleActivator
|
||||
{
|
||||
|
||||
private ServiceRegistration _sr;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception
|
||||
{
|
||||
Server server = new Server(9999);
|
||||
ContextHandlerCollection contexts = new ContextHandlerCollection();
|
||||
server.setHandler(contexts);
|
||||
|
||||
Dictionary serverProps = new Hashtable();
|
||||
//define the unique name of the server instance
|
||||
serverProps.put("managedServerName", "fooServer");
|
||||
//serverProps.put("jetty.http.port", "9999");
|
||||
//register as an OSGi Service for Jetty to find
|
||||
_sr = context.registerService(Server.class.getName(), server, serverProps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the activator.
|
||||
*
|
||||
* @see
|
||||
* org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
_sr.unregister();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>Test OSGi WebApp</h1>
|
||||
<p>Webapp registered by bundle as service successfully deployed.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -31,6 +31,12 @@
|
|||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
|||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
* Bootstrap a webapp
|
||||
|
@ -34,6 +35,9 @@ import org.osgi.framework.BundleContext;
|
|||
public class Activator implements BundleActivator
|
||||
{
|
||||
|
||||
private ServiceRegistration _srA;
|
||||
private ServiceRegistration _srB;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
|
@ -42,29 +46,24 @@ public class Activator implements BundleActivator
|
|||
{
|
||||
String serverName = "defaultJettyServer";
|
||||
|
||||
/* Uncomment to create a different server instance to deploy to. Also change
|
||||
* TestJettyOSGiBootWebAppAsService to use the port 9999
|
||||
|
||||
Server server = new Server();
|
||||
//do any setup on Server in here
|
||||
serverName = "fooServer";
|
||||
Dictionary serverProps = new Hashtable();
|
||||
//define the unique name of the server instance
|
||||
serverProps.put("managedServerName", serverName);
|
||||
serverProps.put("jetty.http.port", "9999");
|
||||
//let Jetty apply some configuration files to the Server instance
|
||||
serverProps.put("jetty.etc.config.urls", "file:/opt/jetty/etc/jetty.xml,file:/opt/jetty/etc/jetty-selector.xml,file:/opt/jetty/etc/jetty-deployer.xml");
|
||||
//register as an OSGi Service for Jetty to find
|
||||
context.registerService(Server.class.getName(), server, serverProps);
|
||||
*/
|
||||
|
||||
|
||||
//Create a webapp context as a Service and target it at the Server created above
|
||||
//Create webappA as a Service and target it at the default server
|
||||
WebAppContext webapp = new WebAppContext();
|
||||
Dictionary props = new Hashtable();
|
||||
props.put("war",".");
|
||||
props.put("war","webappA");
|
||||
props.put("contextPath","/acme");
|
||||
props.put("managedServerName", serverName);
|
||||
context.registerService(ContextHandler.class.getName(),webapp,props);
|
||||
props.put("managedServerName", "defaultJettyServer");
|
||||
_srA = context.registerService(WebAppContext.class.getName(),webapp,props);
|
||||
|
||||
//Create a second webappB as a Service and target it at a custom Server
|
||||
//deployed by another bundle
|
||||
WebAppContext webappB = new WebAppContext();
|
||||
Dictionary propsB = new Hashtable();
|
||||
propsB.put("war", "webappB");
|
||||
propsB.put("contextPath", "/acme");
|
||||
propsB.put("managedServerName", "fooServer");
|
||||
_srB = context.registerService(WebAppContext.class.getName(), webappB, propsB);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,5 +74,7 @@ public class Activator implements BundleActivator
|
|||
*/
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
_srA.unregister();
|
||||
_srB.unregister();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>Test OSGi WebAppA</h1>
|
||||
<p>Webapp registered by bundle as service successfully deployed.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>Test OSGi WebAppB</h1>
|
||||
<p>Webapp registered by bundle as service successfully deployed.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -368,7 +368,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>test-jetty-osgi-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-mock-resources</artifactId>
|
||||
|
|
|
@ -83,7 +83,8 @@ public class TestJettyOSGiBootWebAppAsService
|
|||
options.addAll(Arrays.asList(options(systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value(LOG_LEVEL))));
|
||||
options.addAll(Arrays.asList(options(systemProperty("org.eclipse.jetty.LEVEL").value(LOG_LEVEL))));
|
||||
|
||||
options.addAll(jspDependencies());
|
||||
options.addAll(TestJettyOSGiBootCore.jspDependencies());
|
||||
options.addAll(testDependencies());
|
||||
return options.toArray(new Option[options.size()]);
|
||||
}
|
||||
|
||||
|
@ -107,15 +108,21 @@ public class TestJettyOSGiBootWebAppAsService
|
|||
return options;
|
||||
}
|
||||
|
||||
public static List<Option> jspDependencies()
|
||||
public static List<Option> testDependencies()
|
||||
{
|
||||
List<Option> res = new ArrayList<Option>();
|
||||
|
||||
res.addAll(TestJettyOSGiBootCore.jspDependencies());
|
||||
|
||||
// a bundle that registers a webapp as a service for the jetty osgi core
|
||||
// to pick up and deploy
|
||||
res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("test-jetty-osgi-webapp").versionAsInProject().start());
|
||||
|
||||
|
||||
|
||||
|
||||
//a bundle that registers a new named Server instance
|
||||
res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("test-jetty-osgi-server").versionAsInProject().start());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -123,10 +130,12 @@ public class TestJettyOSGiBootWebAppAsService
|
|||
@Test
|
||||
public void assertAllBundlesActiveOrResolved()
|
||||
{
|
||||
TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
|
||||
//TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
|
||||
TestOSGiUtil.debugBundles(bundleContext);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
|
||||
|
||||
@Test
|
||||
public void testBundle() throws Exception
|
||||
{
|
||||
|
@ -135,22 +144,28 @@ public class TestJettyOSGiBootWebAppAsService
|
|||
try
|
||||
{
|
||||
client.start();
|
||||
|
||||
|
||||
ContentResponse response = client.GET("http://127.0.0.1:" + TestJettyOSGiBootCore.DEFAULT_HTTP_PORT + "/acme/index.html");
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
|
||||
String content = new String(response.getContent());
|
||||
assertTrue(content.indexOf("<h1>Test OSGi WebApp</h1>") != -1);
|
||||
assertTrue(content.indexOf("<h1>Test OSGi WebAppA</h1>") != -1);
|
||||
|
||||
response = client.GET("http://127.0.0.1:" + "9999" + "/acme/index.html");
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
content = new String(response.getContent());
|
||||
assertTrue(content.indexOf("<h1>Test OSGi WebAppB</h1>") != -1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
|
||||
ServiceReference[] refs = bundleContext.getServiceReferences(ContextHandler.class.getName(), null);
|
||||
ServiceReference[] refs = bundleContext.getServiceReferences(WebAppContext.class.getName(), null);
|
||||
assertNotNull(refs);
|
||||
assertEquals(1, refs.length);
|
||||
assertEquals(2, refs.length);
|
||||
WebAppContext wac = (WebAppContext) bundleContext.getService(refs[0]);
|
||||
assertEquals("/acme", wac.getContextPath());
|
||||
wac = (WebAppContext) bundleContext.getService(refs[1]);
|
||||
assertEquals("/acme", wac.getContextPath());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue