Unexpected BindException in Endpoint.publish
KUBOTA Yuji
kubota.yuji at gmail.com
Tue Aug 2 05:33:59 UTC 2016
Hi all,
Could you let me know when this fix will be backport to JDK 8?
We need this backport to migrate our system from JDK 7 to JDK 8.
Thanks,
Yuji
2016-02-10 10:17 GMT+09:00 KUBOTA Yuji <kubota.yuji at gmail.com>:
> Hi Miroslav,
>
> Thank you for your sponsor! : https://bugs.openjdk.java.net/browse/JDK-8146086
>
> Can I ask the schedule when does this fix backport to JDK8 ?
>
> Thanks,
> Yuji
>
> 2015-12-02 22:39 GMT+09:00 Miroslav Kos <miroslav.kos at oracle.com>:
>> Hi Yuji,
>> thanks for the patch - it fixes the issue and looks ok to me. I'll integrate
>> it to standalone JAX-WS repo and it will be integrated into openjdk during
>> next syncup.
>>
>> Thanks
>> Miran
>>
>>
>>
>>
>> On 01/12/15 11:11, KUBOTA Yuji wrote:
>>>
>>> Hi Miroslav and all,
>>>
>>> Could you please review the below issue and patch?
>>>
>>> I got the advice by Alan at net-dev. So I want to ask you.
>>> http://mail.openjdk.java.net/pipermail/net-dev/2015-December/009361.html
>>>
>>> ----
>>> I'm at the HackerGarten @ JavaOne15, and write a patch for OpenJDK
>>> community. This's second times from JavaOne14. :)
>>>
>>> We find an unexpected exception in JAX-WS, so I write a patch to fix it.
>>> We think that this issue may block the migration to JDK9 from JDK7.
>>>
>>> If we bind 0.0.0.0 ( using as wildcard ) to publish multiple as the
>>> following test code, JDK9 (and JDK8) returns "java.net.BindException:
>>> Address already in use.” as the below. But JDK7 does NOT return the
>>> exception.
>>>
>>> - Test code for reproduce
>>> ---
>>> import javax.jws.*;
>>> import javax.xml.ws.*;
>>>
>>> public class WSTest{
>>>
>>> @WebService
>>> public static class Method1{
>>> @WebMethod
>>> public String getMethod1Value(){
>>> return "from Method1";
>>> }
>>> }
>>>
>>> @WebService
>>> public static class Method2{
>>> @WebMethod
>>> public String getMethod2Value(){
>>> return "from Method2";
>>> }
>>> }
>>>
>>> public static void main(String[] args) throws Exception{
>>> Endpoint endPoint1 = Endpoint.publish("http://0.0.0.0:8081/method1",
>>> new
>>> Method1());
>>> Endpoint endPoint2 = Endpoint.publish("http://0.0.0.0:8081/method2",
>>> new
>>> Method2());
>>>
>>> System.out.println("Sleep 3 secs...");
>>>
>>> Thread.sleep(3000);
>>>
>>> endPoint2.stop();
>>> endPoint1.stop();
>>> }
>>>
>>> }
>>> ---
>>>
>>> - StackTrace
>>> ---
>>> Exception in thread "main"
>>> com.sun.xml.internal.ws.server.ServerRtException: Server Runtime
>>> Error: java.net.BindException: Address already in use
>>> at
>>> com.sun.xml.internal.ws.transport.http.server.ServerMgr.createContext(ServerMgr.java:117)
>>> at
>>> com.sun.xml.internal.ws.transport.http.server.HttpEndpoint.publish(HttpEndpoint.java:64)
>>> at
>>> com.sun.xml.internal.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:232)
>>> at
>>> com.sun.xml.internal.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:126)
>>> at javax.xml.ws.Endpoint.publish(Endpoint.java:240)
>>> at wstest.WSTest.main(WSTest.java:27)
>>> Caused by: java.net.BindException: Address already in use
>>> at sun.nio.ch.Net.bind0(Native Method)
>>> at sun.nio.ch.Net.bind(Net.java:432)
>>> at sun.nio.ch.Net.bind(Net.java:424)
>>> at
>>> sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
>>> at
>>> sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
>>> at sun.net.httpserver.ServerImpl.<init>(ServerImpl.java:102)
>>> at
>>> sun.net.httpserver.HttpServerImpl.<init>(HttpServerImpl.java:50)
>>> at
>>> sun.net.httpserver.DefaultHttpServerProvider.createHttpServer(DefaultHttpServerProvider.java:35)
>>> at com.sun.net.httpserver.HttpServer.create(HttpServer.java:130)
>>> at
>>> com.sun.xml.internal.ws.transport.http.server.ServerMgr.createContext(ServerMgr.java:86)
>>> ... 5 more
>>> -----
>>>
>>> To publishes the Endpoint, JAX-WS checks whether the HttpContext has
>>> been created by given address, then creates a HttpContext if do not
>>> exist.
>>> If we sets 0.0.0.0 as given address, JAX-WS checks by
>>> ServerSocket#getLocalSocketAddress() (server local address), so
>>> returns BindException when 0.0.0.0 has been blinded already.
>>>
>>> Why so? JAX_WS-941[1] fixes NPE in Endpoint.stop but do not think
>>> about above situation. And JAX_WS-941 does not back port to JDK7.
>>>
>>> So I write a patch which is based jdk9/dev/jaxws
>>> (changeset:637:2d84c6f4cbba) to fix the BindException with JAX_WS-941.
>>>
>>> Please review this patch :)
>>>
>>> [1]: https://java.net/jira/browse/JAX_WS-941
>>>
>>> - Patch
>>> ---
>>> diff -r 2d84c6f4cbba
>>>
>>> src/java.xml.ws/share/classes/com/sun/xml/internal/ws/transport/http/server/ServerMgr.java
>>> ---
>>> a/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/transport/http/server/ServerMgr.java
>>> Thu Oct 22 08:47:47 2015 -0700
>>> +++
>>> b/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/transport/http/server/ServerMgr.java
>>> Tue Oct 27 19:48:35 2015 +0900
>>> @@ -38,6 +38,7 @@
>>> import java.util.concurrent.ExecutorService;
>>> import java.util.concurrent.Executors;
>>> import java.util.logging.Logger;
>>> +import java.util.Optional;
>>>
>>> /**
>>> * Manages all the WebService HTTP servers created by JAXWS runtime.
>>> @@ -81,24 +82,38 @@
>>> synchronized(servers) {
>>> state = servers.get(inetAddress);
>>> if (state == null) {
>>> - logger.fine("Creating new HTTP Server at
>>> "+inetAddress);
>>> - // Creates server with default socket backlog
>>> - server = HttpServer.create(inetAddress, 0);
>>> - server.setExecutor(Executors.newCachedThreadPool());
>>> - String path = url.toURI().getPath();
>>> - logger.fine("Creating HTTP Context at = "+path);
>>> - HttpContext context = server.createContext(path);
>>> - server.start();
>>> + final int finalPortNum = port;
>>> + Optional<ServerState> stateOpt =
>>> + servers.values()
>>> + .stream()
>>> + .filter(s -> s.getServer()
>>> + .getAddress()
>>> + .getPort() ==
>>> finalPortNum)
>>> + .findAny();
>>>
>>> - // we have to get actual inetAddress from server,
>>> which can differ from the original in some cases.
>>> - // e.g. A port number of zero will let the system
>>> pick up an ephemeral port in a bind operation,
>>> - // or IP: 0.0.0.0 - which is used to monitor
>>> network traffic from any valid IP address
>>> - inetAddress = server.getAddress();
>>> + if (inetAddress.getAddress().isAnyLocalAddress() &&
>>> + stateOpt.isPresent()) {
>>> + state = stateOpt.get();
>>> + } else {
>>> + logger.fine("Creating new HTTP Server at
>>> "+inetAddress);
>>> + // Creates server with default socket backlog
>>> + server = HttpServer.create(inetAddress, 0);
>>> +
>>> server.setExecutor(Executors.newCachedThreadPool());
>>> + String path = url.toURI().getPath();
>>> + logger.fine("Creating HTTP Context at = "+path);
>>> + HttpContext context = server.createContext(path);
>>> + server.start();
>>>
>>> - logger.fine("HTTP server started = "+inetAddress);
>>> - state = new ServerState(server, path);
>>> - servers.put(inetAddress, state);
>>> - return context;
>>> + // we have to get actual inetAddress from
>>> server, which can differ from the original in some cases.
>>> + // e.g. A port number of zero will let the
>>> system pick up an ephemeral port in a bind operation,
>>> + // or IP: 0.0.0.0 - which is used to monitor
>>> network traffic from any valid IP address
>>> + inetAddress = server.getAddress();
>>> +
>>> + logger.fine("HTTP server started =
>>> "+inetAddress);
>>> + state = new ServerState(server, path);
>>> + servers.put(inetAddress, state);
>>> + return context;
>>> + }
>>> }
>>> }
>>> server = state.getServer();
>>> ---
>>>
>>> Thanks,
>>> Yuji
>>
>>
More information about the core-libs-dev
mailing list