Why is inet: /0.0.0.0 interpreted as inet: / 0: 0: 0: 0: 0: 0: 0: 0 by com.sun.net.httpserver.HttpServer?

We found this problem when implementing the reconnection logic for the WS endpoint using the JAX-WS stack deployed on the Glassfishv2.1 server. We deploy the web service in a cluster environment. To simplify the deployment, we use 0.0.0.0 as the IP address at which the endpoint must be published so that it can be accessed from all available IP addresses related to the cluster nodes. The following is a snippet of code to initialize WS (Web Services):

import javax.xml.ws.Endpoint; . . //Implementor is the corresponding implementation object for the WS Endpoint receiver = Endpoint.create(new Implementor()); . receiver.setExecutor(threadPoolExecutor); receiver.publish ("http://0.0.0.0:9545/context"); 

We call the receiver.stop () method to stop publishing the endpoint in our cleanup code. That we get a null pointer exception with the following stack trace:

 java.lang.NullPointerException at com.sun.xml.ws.transport.http.server.ServerMgr.removeContext(ServerMgr.java:123) at com.sun.xml.ws.transport.http.server.HttpEndpoint.stop(HttpEndpoint.java:110) at com.sun.xml.ws.transport.http.server.EndpointImpl.stop(EndpointImpl.java:167 

When trying to find the cause of the NPE, we found that the ServerMgr class depends on InetSocketAddress HttpServer, which listens on the ip port of the URL where the WS endpoint is published to get status information from the map. Since the address inet inet: /0.0.0.0 is interpreted as "inet: / 0: 0: 0: 0: 0: 0: 0: 0", he could not find the record on the map and, therefore, NPE. Here is the source code for ServerMgr.

To prove that this is actually a problem, we tried to replicate the logic of the ServerMgr code associated with InetSocketAddress as the following program:

 import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpServer; import java.io.IOException; import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public class Main { static final String URL_1 = "http://0.0.0.0:9545/context"; static final String URL_2 = "http://127.0.0.1:9548/context"; static final String URL_3 = "http://10.226.90.217:9549/context"; public void testUrl(String address){ try { URL url = new URL(address); Map<InetSocketAddress, Integer> map = new HashMap<InetSocketAddress, Integer>(); InetSocketAddress iaddr = new InetSocketAddress(url.getHost(), url.getPort()); map.put(iaddr, 1); HttpServer server = HttpServer.create(iaddr, 5); HttpContext context = server.createContext(url.toURI().getPath()); server.start(); System.out.println("original inet:"+iaddr+" and final inet:"+context.getServer().getAddress()); if(iaddr.equals(context.getServer().getAddress())){ System.out.println("equal"); Integer t = map.get(context.getServer().getAddress()); if( t == null){ System.out.println("You won"); }else{ System.out.println("You lose "+t); } }else{ System.out.println("not-equal"); } server.stop(0); map.clear(); } catch (URISyntaxException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } } public static void main(String[] args) { Main d = new Main(); d.testUrl(Main.URL_1); d.testUrl(Main.URL_2); d.testUrl(Main.URL_3); } } 

Oddly enough, we get the following result in my WindowsXP window (Java version 1.6.0_22)

  equal-- original inet:/0.0.0.0:9545 and final inet:/0.0.0.0:9545 equal You lose 1 equal-- original inet:/127.0.0.1:9548 and final inet:/127.0.0.1:9548 equal You lose 1 equal-- original inet:/10.226.92.47:9549 and final inet:/10.226.92.47:9549 equal You lose 1 

and the following output in my dev block (Linux tahoe 2.6.9-67.EL # 1 Wed Nov 7 13:43:31 EST 2007 x86_64 x86_64 x86_64 GNU / Linux) (Java Version 1.6.0_17)

 run: original inet:/0.0.0.0:9545 and final inet:/0:0:0:0:0:0:0:0:9545 not-equal original inet:/127.0.0.1:9548 and final inet:/127.0.0.1:9548 equal You lose 1 original inet:/10.226.90.217:9549 and final inet:/10.226.90.217:9549 equal You lose 1 

Based on the background - I have two questions:

  • a. Why is 0.0.0.0 interpreted as an IPv6 address? (Also, is this a problem with the OS or JRE? Is this a bug or a feature? Etc.)
  • b. Do we have a way to configure the JRE to interpret 0.0.0.0 as an IPv4 address? (We want to use 0.0.0.0 as the endpoint of the address, as it simplifies the deployment of our web service)
+4
source share
2 answers

Have you tried selecting IPv4 as a variable for the java executable?

 -Djava.net.preferIPv4Stack=true 

Look here and here ..

You can also force IPv4 from your code using System.setProperty("java.net.preferIPv4Stack" , "true");

0
source

You can replace 0.0.0.0 with InetAddress.getLocalHost().getHostAddress(); It will automatically resolve correctly and there is no need - -Djava.net.preferIPv4Stack=true

+3
source

All Articles