From 669c70885fdcd69fe344ec9ed38bab60005a9b9d Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Fri, 27 Jul 2018 21:21:49 +1000 Subject: [PATCH 1/2] issue #2718 prevent NPE and IAE when changing Executor Signed-off-by: olivier lamy --- jetty-http-spi/pom.xml | 28 ++++++ .../jetty/http/spi/JettyHttpServer.java | 29 +++++-- .../TestEndpointMultiplePublishProblem.java | 85 +++++++++++++++++++ 3 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 1cd783788bd..11b024ba155 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -67,4 +67,32 @@ + + + jdk9 + + [1.9,) + + + + javax.xml + jaxws-api + 2.0EA3 + test + + + com.sun.xml.ws + jaxws-rt + 2.3.0.2 + test + + + javax.activation + javax.activation-api + 1.2.0 + test + + + + diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java index 8ba4ad3054b..cb0a3754af0 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java @@ -59,9 +59,9 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer private InetSocketAddress _addr; - private Map _contexts = new HashMap(); + private Map _contexts = new HashMap<>(); - private Map _connectors = new HashMap(); + private Map _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 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 diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java new file mode 100644 index 00000000000..539a549a04d --- /dev/null +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestEndpointMultiplePublishProblem.java @@ -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"; + } + } +} From 492361a6161893f9964c2c473a24dd07d9bda946 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 22 Aug 2018 18:22:10 +1000 Subject: [PATCH 2/2] as the jvm start and do some setup we must start all test with a fresh jvm Signed-off-by: olivier lamy --- jetty-http-spi/pom.xml | 7 +++++++ .../eclipse/jetty/http/spi/TestSPIServer.java | 18 ++---------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 11b024ba155..eb6337021c5 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -45,6 +45,13 @@ org.eclipse.jetty.http.spi.* + + org.apache.maven.plugins + maven-surefire-plugin + + false + + org.apache.felix maven-bundle-plugin diff --git a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java index fb27dfe0f2c..dc54a27634e 100644 --- a/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java +++ b/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java @@ -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")