Merge remote-tracking branch 'origin/jetty-9.2.x'

This commit is contained in:
Greg Wilkins 2014-12-04 14:17:47 +01:00
commit a04a576c45
5 changed files with 165 additions and 121 deletions

View File

@ -44,11 +44,13 @@ public class JettyJspServlet extends JspServlet
*/ */
private static final long serialVersionUID = -5387857473125086791L; private static final long serialVersionUID = -5387857473125086791L;
@Override @Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{ {
HttpServletRequest request = null; HttpServletRequest request = null;
if (req instanceof HttpServletRequest) if (req instanceof HttpServletRequest)
request = (HttpServletRequest)req; request = (HttpServletRequest)req;
@ -74,23 +76,31 @@ public class JettyJspServlet extends JspServlet
} }
String pathInContext = URIUtil.addPaths(servletPath,pathInfo); String pathInContext = URIUtil.addPaths(servletPath,pathInfo);
if (pathInContext.endsWith("/")) String jspFile = getInitParameter("jspFile");
//if this is a forced-path from a jsp-file, we want the jsp servlet to handle it,
//otherwise the default servlet might handle it
if (jspFile == null)
{ {
//dispatch via forward to the default servlet if (pathInContext.endsWith("/"))
getServletContext().getNamedDispatcher("default").forward(req, resp);
return;
}
else
{
//check if it resolves to a directory
Resource resource = ((ContextHandler.Context)getServletContext()).getContextHandler().getResource(pathInContext);
if (resource!=null && resource.isDirectory())
{ {
//dispatch via forward to the default servlet //dispatch via forward to the default servlet
getServletContext().getNamedDispatcher("default").forward(req, resp); getServletContext().getNamedDispatcher("default").forward(req, resp);
return; return;
} }
else
{
//check if it resolves to a directory
Resource resource = ((ContextHandler.Context)getServletContext()).getContextHandler().getResource(pathInContext);
if (resource!=null && resource.isDirectory())
{
//dispatch via forward to the default servlet
getServletContext().getNamedDispatcher("default").forward(req, resp);
return;
}
}
} }
//fall through to the normal jsp servlet handling //fall through to the normal jsp servlet handling

View File

@ -75,25 +75,30 @@ public class JettyJspServlet extends JspServlet
} }
String pathInContext = URIUtil.addPaths(servletPath,pathInfo); String pathInContext = URIUtil.addPaths(servletPath,pathInfo);
String jspFile = getInitParameter("jspFile");
if (pathInContext.endsWith("/")) //if the request is for a jsp file then fall through to the jsp servlet
if (jspFile == null)
{ {
//dispatch via forward to the default servlet if (pathInContext.endsWith("/"))
getServletContext().getNamedDispatcher("default").forward(req, resp);
return;
}
else
{
//check if it resolves to a directory
Resource resource = ((ContextHandler.Context)getServletContext()).getContextHandler().getResource(pathInContext);
if (resource!=null && resource.isDirectory())
{ {
//dispatch via forward to the default servlet //dispatch via forward to the default servlet
getServletContext().getNamedDispatcher("default").forward(req, resp); getServletContext().getNamedDispatcher("default").forward(req, resp);
return; return;
} }
else
{
//check if it resolves to a directory
Resource resource = ((ContextHandler.Context)getServletContext()).getContextHandler().getResource(pathInContext);
if (resource!=null && resource.isDirectory())
{
//dispatch via forward to the default servlet
getServletContext().getNamedDispatcher("default").forward(req, resp);
return;
}
}
} }
//fall through to the normal jsp servlet handling //fall through to the normal jsp servlet handling
super.service(req, resp); super.service(req, resp);
} }

View File

@ -32,6 +32,7 @@ import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration; import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.BundleTracker; import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.ServiceTracker;
/** /**
* JettyBootstrapActivator * JettyBootstrapActivator
@ -56,14 +57,12 @@ public class JettyBootstrapActivator implements BundleActivator
private ServiceRegistration _registeredServer; private ServiceRegistration _registeredServer;
private ServiceWatcher _jettyContextHandlerTracker; private ServiceTracker _contextHandlerTracker;
private PackageAdminServiceTracker _packageAdminServiceTracker; private PackageAdminServiceTracker _packageAdminServiceTracker;
private BundleTracker _webBundleTracker; private BundleTracker _webBundleTracker;
private BundleContext _bundleContext;
private JettyServerServiceTracker _jettyServerServiceTracker; private JettyServerServiceTracker _jettyServerServiceTracker;
@ -79,8 +78,8 @@ public class JettyBootstrapActivator implements BundleActivator
*/ */
public void start(final BundleContext context) throws Exception public void start(final BundleContext context) throws Exception
{ {
try {
INSTANCE = this; INSTANCE = this;
_bundleContext = context;
// track other bundles and fragments attached to this bundle that we // track other bundles and fragments attached to this bundle that we
// should activate. // should activate.
@ -90,12 +89,12 @@ public class JettyBootstrapActivator implements BundleActivator
_jettyServerServiceTracker = new JettyServerServiceTracker(); _jettyServerServiceTracker = new JettyServerServiceTracker();
context.addServiceListener(_jettyServerServiceTracker, "(objectclass=" + Server.class.getName() + ")"); context.addServiceListener(_jettyServerServiceTracker, "(objectclass=" + Server.class.getName() + ")");
// track ContextHandler class instances and deploy them to one of the known Servers
_jettyContextHandlerTracker = new ServiceWatcher();
context.addServiceListener(_jettyContextHandlerTracker, "(objectclass=" + ContextHandler.class.getName() + ")");
// Create a default jetty instance right now. // Create a default jetty instance right now.
Server defaultServer = DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); 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 //Create a bundle tracker to help deploy webapps and ContextHandlers
BundleWatcher bundleTrackerCustomizer = new BundleWatcher(); BundleWatcher bundleTrackerCustomizer = new BundleWatcher();
@ -103,6 +102,7 @@ public class JettyBootstrapActivator implements BundleActivator
_webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, bundleTrackerCustomizer); _webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, bundleTrackerCustomizer);
bundleTrackerCustomizer.setBundleTracker(_webBundleTracker); bundleTrackerCustomizer.setBundleTracker(_webBundleTracker);
bundleTrackerCustomizer.open(); bundleTrackerCustomizer.open();
} catch (Exception e) { e.printStackTrace();}
} }
@ -123,10 +123,10 @@ public class JettyBootstrapActivator implements BundleActivator
_webBundleTracker.close(); _webBundleTracker.close();
_webBundleTracker = null; _webBundleTracker = null;
} }
if (_jettyContextHandlerTracker != null) if (_contextHandlerTracker != null)
{ {
context.removeServiceListener(_jettyContextHandlerTracker); _contextHandlerTracker.close();
_jettyContextHandlerTracker = null; _contextHandlerTracker = null;
} }
if (_jettyServerServiceTracker != null) if (_jettyServerServiceTracker != null)
{ {

View File

@ -33,10 +33,9 @@ import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil; import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/** /**
* ServiceWatcher * ServiceWatcher
@ -47,9 +46,9 @@ import org.osgi.util.tracker.ServiceTracker;
* *
* ContextHandlers and WebApps can also be deployed into jetty without creating them as * 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 * osgi services. Instead, they can be deployed via manifest headers inside bundles. See
* {@link WebBundleTrackerCustomizer}. * {@link BundleWatcher}.
*/ */
public class ServiceWatcher implements ServiceListener public class ServiceWatcher implements ServiceTrackerCustomizer
{ {
private static Logger LOG = Log.getLogger(ServiceWatcher.class); private static Logger LOG = Log.getLogger(ServiceWatcher.class);
@ -104,97 +103,127 @@ public class ServiceWatcher implements ServiceListener
return candidates; 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 reference
* @return
*/
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);
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Receives notification that a service has had a lifecycle change. * Undeploy a ContextHandler that is a Service.
* *
* @param ev The <code>ServiceEvent</code> object. * @param reference
*/ */
/** public void removeService (BundleContext context, ContextHandler contextHandler, ServiceReference reference)
* @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
*/
public void serviceChanged(ServiceEvent ev)
{ {
ServiceReference sr = ev.getServiceReference(); //Get a jetty deployer targetted to the named server instance, or the default one if not named
switch (ev.getType()) //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)
{ {
case ServiceEvent.MODIFIED: boolean removed = false;
case ServiceEvent.UNREGISTERING: Iterator<Entry<ServiceReference, ServiceProvider>> itor = candidates.entrySet().iterator();
while (!removed && itor.hasNext())
{ {
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext(); Entry<ServiceReference, ServiceProvider> e = itor.next();
ContextHandler contextHandler = (ContextHandler) context.getService(sr); try
//if this was not a service that another of our deployers may have deployed (in which case they will undeploy it)
String watermark = (String)sr.getProperty(OSGiWebappConstants.WATERMARK);
//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)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
Map<ServiceReference, ServiceProvider> candidates = getDeployers(serverName);
if (candidates != null)
{ {
boolean removed = false; removed = e.getValue().serviceRemoved(reference, contextHandler);
Iterator<Entry<ServiceReference, ServiceProvider>> itor = candidates.entrySet().iterator();
while (!removed && itor.hasNext())
{
Entry<ServiceReference, ServiceProvider> e = itor.next();
try
{
removed = e.getValue().serviceRemoved(sr, contextHandler);
}
catch (Exception x)
{
LOG.warn("Error undeploying service representing jetty context ", x);
}
}
} }
} catch (Exception x)
if (ev.getType() == ServiceEvent.UNREGISTERING)
{
break;
}
else
{
// modified, meaning: we reload it. now that we stopped it;
// we can register it.
}
case ServiceEvent.REGISTERED:
{
Bundle contributor = sr.getBundle();
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
ContextHandler contextHandler = (ContextHandler) context.getService(sr);
if (contextHandler.getServer() != null)
{ {
// is configured elsewhere. LOG.warn("Error undeploying service representing jetty context ", x);
return;
} }
String watermark = (String)sr.getProperty(OSGiWebappConstants.WATERMARK);
if (watermark != null && !"".equals(watermark))
return; //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)sr.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(sr, contextHandler);
if (added && LOG.isDebugEnabled())
LOG.debug("Provider "+e.getValue()+" deployed "+contextHandler);
}
catch (Exception x)
{
LOG.warn("Error deploying service representing jetty context", x);
}
}
}
break;
} }
} }
} }

View File

@ -140,7 +140,7 @@ public class AsyncServletIOTest
public void testBigWrites() throws Exception public void testBigWrites() throws Exception
{ {
process(102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400); process(102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400,102400);
Assert.assertThat("On Write Possible",_owp.get(),greaterThan(1)); Assert.assertThat("On Write Possible",_owp.get(),greaterThanOrEqualTo(1));
} }
@Test @Test