Merge pull request #2748 from olamy/bugfix/2718_NPE_HttpServerProvider

Issue #2718 - prevent NPE and IAE when changing Executor
This commit is contained in:
Joakim Erdfelt 2018-08-22 11:48:25 -05:00 committed by GitHub
commit 9a06acc846
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 144 additions and 23 deletions

View File

@ -45,6 +45,13 @@
<onlyAnalyze>org.eclipse.jetty.http.spi.*</onlyAnalyze>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
@ -67,4 +74,32 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>jdk9</id>
<activation>
<jdk>[1.9,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.0EA3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -59,9 +59,9 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
private InetSocketAddress _addr;
private Map<String, JettyHttpContext> _contexts = new HashMap<String, JettyHttpContext>();
private Map<String, JettyHttpContext> _contexts = new HashMap<>();
private Map<String, Connector> _connectors = new HashMap<String, Connector>();
private Map<String, Connector> _connectors = new HashMap<>();
public JettyHttpServer(Server server, boolean shared)
@ -84,13 +84,14 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
@Override
public void bind(InetSocketAddress addr, int backlog) throws IOException
{
this._addr = addr;
// check if there is already a connector listening
Collection<NetworkConnector> connectors = _server.getBeans(NetworkConnector.class);
if (connectors != null)
{
for (NetworkConnector connector : connectors)
{
if (connector.getPort() == addr.getPort()) {
if (connector.getPort() == addr.getPort()||connector.getLocalPort() == addr.getPort()) {
if (LOG.isDebugEnabled()) LOG.debug("server already bound to port " + addr.getPort() + ", no need to rebind");
return;
}
@ -100,7 +101,7 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
if (_serverShared)
throw new IOException("jetty server is not bound to port " + addr.getPort());
this._addr = addr;
if (LOG.isDebugEnabled()) LOG.debug("binding server to port " + addr.getPort());
ServerConnector connector = new ServerConnector(_server);
@ -153,9 +154,23 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
throw new IllegalArgumentException("missing required 'executor' argument");
ThreadPool threadPool = _server.getThreadPool();
if (threadPool instanceof DelegatingThreadPool)
((DelegatingThreadPool)_server.getThreadPool()).setExecutor(executor);
else
throw new UnsupportedOperationException("!DelegatingThreadPool");
{
try
{
if (_server.isRunning())
{
_server.stop();
}
((DelegatingThreadPool) _server.getThreadPool()).setExecutor(executor);
_server.start();
}
catch ( Exception e )
{
throw new RuntimeException(e.getMessage(), e);
}
} else {
throw new UnsupportedOperationException( "!DelegatingThreadPool" );
}
}
@Override

View File

@ -0,0 +1,85 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.http.spi;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
public class TestEndpointMultiplePublishProblem
{
private static String default_impl = System.getProperty("com.sun.net.httpserver.HttpServerProvider");
@BeforeClass
public static void change_Impl()
{
System.setProperty("com.sun.net.httpserver.HttpServerProvider", JettyHttpServerProvider.class.getName());
}
@AfterClass
public static void restore_Impl()
{
if(default_impl != null)
{
System.setProperty( "com.sun.net.httpserver.HttpServerProvider", default_impl );
}
}
@Test
public void mainJetty() throws Exception {
Server jettyWebServer = new Server(new DelegatingThreadPool(new QueuedThreadPool()));
ServerConnector connector = new ServerConnector(jettyWebServer);
connector.setHost("localhost");
connector.setPort(0);
connector.setReuseAddress(true);
jettyWebServer.addConnector(connector);
jettyWebServer.setHandler(new ContextHandlerCollection());
JettyHttpServerProvider.setServer(jettyWebServer);
jettyWebServer.start();
Endpoint.publish(String.format("http://%s:%d/hello", "localhost", 0), new Ws());
// Comment out the below line for success in later java such as java8_u172, works before u151 or so
Endpoint.publish(String.format("http://%s:%d/hello2", "localhost", 0), new Ws());
int port = connector.getLocalPort();
System.out.printf("Started, check: http://localhost:%d/hello?wsdl%n", port);
}
@WebService
public static class Ws {
@WebMethod
public String hello() {
return "Hello";
}
}
}

View File

@ -71,12 +71,7 @@ public class TestSPIServer
server = new JettyHttpServerProvider().createHttpServer(null, 10);
final HttpContext httpContext = server.createContext("/",
new HttpHandler()
{
@Override
public void handle(HttpExchange exchange) throws IOException
{
exchange -> {
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type","text/plain");
exchange.sendResponseHeaders(200,0);
@ -93,8 +88,6 @@ public class TestSPIServer
responseBody.write(s.getBytes());
}
responseBody.close();
}
});
httpContext.setAuthenticator(new BasicAuthenticator("Test")
@ -161,12 +154,7 @@ public class TestSPIServer
InetSocketAddress("localhost", 0), 10);
final HttpContext httpContext = server.createContext("/",
new HttpHandler()
{
@Override
public void handle(HttpExchange exchange) throws IOException
{
exchange -> {
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type","text/plain");
exchange.sendResponseHeaders(200,0);
@ -183,8 +171,6 @@ public class TestSPIServer
responseBody.write(s.getBytes());
}
responseBody.close();
}
});
httpContext.setAuthenticator(new BasicAuthenticator("Test")