Unexpected BindException in Endpoint.publish

KUBOTA Yuji kubota.yuji at gmail.com
Thu Aug 4 00:35:47 UTC 2016


Hi Aleksej,

Thank you very much!
If you need some help about the patch, please mention me :)

Thanks,
Yuji

2016-08-03 19:56 GMT+09:00 Aleks Efimov <aleksej.efimov at oracle.com>:
> Hi Yuji,
>
> I've created JDK8 backport [1] for this issue and will work on it in the
> upcoming months.
>
> Best Regards,
>
> Aleksej
>
> [1] https://bugs.openjdk.java.net/browse/JDK-8162941
>
>
>
> On 02/08/16 08:33, KUBOTA Yuji wrote:
>>
>> 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