Make configuration of acceptors and selectors compatible with Jetty 8

The ServerConnector class doesn’t exist in Jetty 8 so we have to
resort to reflection to create and configure a SelectChannelConnector
instead.

Closes gh-5649
See gh-5380
This commit is contained in:
Andy Wilkinson 2016-04-11 20:51:55 +01:00
parent fa142d929a
commit 69499bf329
2 changed files with 68 additions and 13 deletions

View File

@ -1,3 +1,2 @@
server.compression.enabled: true
server.compression.min-response-size: 1
server.jetty.acceptors=2

View File

@ -105,6 +105,8 @@ public class JettyEmbeddedServletContainerFactory
private static final String GZIP_HANDLER_JETTY_9_3 = "org.eclipse.jetty.server.handler.gzip.GzipHandler";
private static final String CONNECTOR_JETTY_8 = "org.eclipse.jetty.server.nio.SelectChannelConnector";
private List<Configuration> configurations = new ArrayList<Configuration>();
private boolean useForwardHeaders;
@ -176,22 +178,20 @@ public class JettyEmbeddedServletContainerFactory
}
private Server createServer(InetSocketAddress address) {
if (this.acceptors < 0 && this.selectors < 0) {
return new Server(address);
}
if (!ClassUtils.isPresent("org.eclipse.jetty.server.ServerConnector", null)) {
this.logger.warn("Acceptors and Selectors are not supported with Jetty 8");
return new Server(address);
}
Server server = new Server();
ServerConnector connector = new ServerConnector(server, this.acceptors,
this.selectors);
connector.setHost(address.getHostName());
connector.setPort(address.getPort());
server.setConnectors(new Connector[] { connector });
server.setConnectors(new Connector[] { createConnector(address, server) });
return server;
}
private AbstractConnector createConnector(InetSocketAddress address, Server server) {
if (ClassUtils.isPresent(CONNECTOR_JETTY_8, getClass().getClassLoader())) {
return new Jetty8ConnectorFactory().createConnector(server, address,
this.acceptors, this.selectors);
}
return new Jetty9ConnectorFactory().createConnector(server, address,
this.acceptors, this.selectors);
}
private Handler addHandlerWrappers(Handler handler) {
if (getCompression() != null && getCompression().getEnabled()) {
handler = applyWrapper(handler, createGzipHandler());
@ -802,4 +802,60 @@ public class JettyEmbeddedServletContainerFactory
}
private interface ConnectorFactory {
AbstractConnector createConnector(Server server, InetSocketAddress address,
int acceptors, int selectors);
}
private static class Jetty8ConnectorFactory implements ConnectorFactory {
@Override
public AbstractConnector createConnector(Server server, InetSocketAddress address,
int acceptors, int selectors) {
try {
Class<?> connectorClass = ClassUtils.forName(CONNECTOR_JETTY_8,
getClass().getClassLoader());
AbstractConnector connector = (AbstractConnector) connectorClass
.newInstance();
ReflectionUtils.findMethod(connectorClass, "setPort", int.class)
.invoke(connector, address.getPort());
ReflectionUtils.findMethod(connectorClass, "setHost", String.class)
.invoke(connector, address.getHostName());
if (acceptors > 0) {
ReflectionUtils.findMethod(connectorClass, "setAcceptors", int.class)
.invoke(connector, acceptors);
}
if (selectors > 0) {
Object selectorManager = ReflectionUtils
.findMethod(connectorClass, "getSelectorManager")
.invoke(connector);
ReflectionUtils.findMethod(selectorManager.getClass(),
"setSelectSets", int.class)
.invoke(selectorManager, selectors);
}
return connector;
}
catch (Exception ex) {
throw new RuntimeException("Failed to configure Jetty 8 connector", ex);
}
}
}
private static class Jetty9ConnectorFactory implements ConnectorFactory {
@Override
public AbstractConnector createConnector(Server server, InetSocketAddress address,
int acceptors, int selectors) {
ServerConnector connector = new ServerConnector(server, acceptors, selectors);
connector.setHost(address.getHostName());
connector.setPort(address.getPort());
return connector;
}
}
}