Unexpected BindException in Endpoint.publish
Aleks Efimov
aleksej.efimov at oracle.com
Wed Aug 3 10:56:18 UTC 2016
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