我们在使用部署在Glassfishv2.1服务器上的JAX-WS堆栈为WS端点实现重新连接逻辑时发现了这个问题。我们在集群环境中部署Web服务。为了简化部署,我们使用0.0.0.0作为端点需要发布的IP,以便可以从与集群节点相关的所有可用IP访问它。以下是用于初始化WS(Web服务)的代码片段:
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");
我们调用receiver.stop()来停止在清理代码中发布端点。这就是我们收到带有以下堆栈跟踪的空指针异常的地方:
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
在尝试查找NPE的原因时,我们发现ServerMgr类依赖于HttpServer的InetSocketAddress,它侦听发布WS端点的URL的ip:端口,以从中检索某些状态信息。地图。由于inet地址“inet:/0.0.0.0”被解释为“inet:/ 0:0:0:0:0:0:0:0”,因此无法在地图中找到条目,因此无法找到NPE。 Here is the source code of ServerMgr.
为了证明这实际上是问题所在,我们尝试将与InetSocketAddress相关的ServerMgr代码的逻辑复制为以下程序:
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);
}
}
奇怪的是,我在WindowsXP框(Java版本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
和我的开发框上的以下输出 (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版本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
根据背景 - 我有两个问题: