Java 8u162中javax.xml.ws.Endpoint.publish抛出NPE问题求助
我之前碰到过完全一样的问题,这是Java 8u162对JAX-WS内置HTTP服务器管理逻辑调整后引入的已知bug,核心原因是com.sun.xml.internal.ws.transport.http.server.ServerMgr在复用共享HttpServer实例时,没有正确处理多端点注册的上下文初始化,导致发布第二个端点时触发空指针异常(NPE)。
问题根因
Java 8u162修改了ServerMgr的getServer方法逻辑:当第一个端点发布后,它会缓存创建的HttpServer实例;但第二个端点发布时,复用该实例后没有正确初始化端点注册所需的内部状态,导致后续调用中访问了未初始化的对象,抛出NPE。
可行解决方案
1. 手动创建并共享HttpServer实例(推荐)
绕过ServerMgr的自动管理,显式创建HttpServer并为每个端点绑定独立的上下文,彻底避免复用逻辑的bug:
import com.sun.net.httpserver.HttpServer; import javax.xml.ws.Endpoint; import java.net.InetSocketAddress; public class MultiEndpointPublisher { public static void main(String[] args) throws Exception { // 创建共享的HttpServer,指定端口和请求队列大小 HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 10); httpServer.start(); // 发布第一个Web服务端点 Endpoint firstEndpoint = Endpoint.create(new YourFirstWebServiceImpl()); firstEndpoint.publish(httpServer.createContext("/service/v1")); // 发布第二个Web服务端点 Endpoint secondEndpoint = Endpoint.create(new YourSecondWebServiceImpl()); secondEndpoint.publish(httpServer.createContext("/service/v2")); } }
2. 临时降级到Java 8u151
如果暂时无法修改代码,可以先回退到8u151版本,恢复原有正常的多端点发布逻辑,同时规划后续的代码改造或版本升级。
3. 升级到修复后的Java版本
Oracle在Java 8u171及后续的补丁版本中修复了这个ServerMgr的NPE问题。如果不想修改代码,可以直接升级到8u171或更高的Java 8更新版本;也可以考虑迁移到Java 11+(注意:Java 11及以后移除了内置JAX-WS,需要手动引入第三方依赖,比如GlassFish的jaxws-rt)。
验证建议
如果想确认ServerMgr的代码差异,可以用JD-GUI等反编译工具,分别查看Java 8u151和8u162中的com.sun.xml.internal.ws.transport.http.server.ServerMgr类,对比getServer和registerEndpoint方法的实现,就能看到8u162中新增的复用逻辑遗漏了关键的上下文初始化步骤。
内容的提问来源于stack exchange,提问作者Andrew T.

