升级Java 8后WebSphere HTTP调用出现URI can't be null异常求助
Java 6升8后WebSphere下HTTP调用URI异常的排查与解决
嘿,我帮你梳理下这个问题的来龙去脉,以及对应的解决办法:
为什么会出现这个异常?
从你贴的异常栈和代码来看,这个IllegalArgumentException: URI can't be null是在代理选择器DefaultProxySelector.select()里抛出来的。核心原因是Java 8对URL的解析逻辑比Java 6严格了很多,尤其是对URL路径的格式要求。
看你创建URL的代码:
URL url = new URL("http", cicsIp, cicsPort, callData);
这里的callData经过setLength处理后,大概率是没有以/开头——Java 6对这种不规范的路径会睁一只眼闭一只眼,但Java 8会严格遵循RFC规范,要求URL路径必须以/开头,否则内部生成URI时会出现null,进而触发这个异常。
快速修复方案
方案1:给路径补个开头的/
最简单的办法就是在创建URL前,确保callData是以/开头的:
// 检查并补全路径开头的/ if (!callData.startsWith("/")) { callData = "/" + callData; } URL url = new URL("http", cicsIp, cicsPort, callData);
这样就能让Java 8正确解析路径,生成合法的URI,避免null的问题。
方案2:改用URI来构建URL(更稳妥)
Java 8里推荐先用URI类来构建,它的解析逻辑更清晰,容错性也更好:
// 先构造URI,再转成URL URI uri = new URI("http", null, cicsIp, cicsPort, callData, null, null); URL url = uri.toURL();
URI的构造方法会自动处理路径格式的小问题,比直接用URL构造器靠谱。
长期替代方案:换用更现代的HTTP客户端
如果原生的URLConnection在Java版本升级后问题不断,我强烈推荐换成Apache HttpClient(兼容Java 8),它是目前Java生态里最成熟的HTTP客户端之一。
举个Apache HttpClient的例子:
首先在你的项目里引入依赖(Maven为例):
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.14</version> </dependency>
然后修改你的调用代码:
import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; // ... 其他原有代码 try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // 拼接完整URL,确保路径格式正确 String fullUrl = "http://" + cicsIp + ":" + cicsPort + (callData.startsWith("/") ? "" : "/") + callData; HttpGet httpGet = new HttpGet(fullUrl); try (CloseableHttpResponse response = httpClient.execute(httpGet)) { HttpEntity entity = response.getEntity(); if (entity != null) { String result = EntityUtils.toString(entity); // 沿用你原有的结果处理逻辑 responseData = new StringBuffer(result.substring(56)); // 这里不需要逐行读,EntityUtils已经把所有内容取出来了 } } } catch (Exception e) { throw new CicsException(e); }
这种方式不仅兼容性更好,还支持连接池、超时配置等高级功能,比原生URLConnection好用太多。
额外要注意的点
- 检查
setLength处理后的callData有没有特殊字符(比如空格、中文),Java 8对URL编码的要求更严,必要时用URLEncoder.encode()对参数部分单独编码(别编码整个URL)。 - 确保你的WebSphere 8.5已经装了支持Java 8的补丁——WebSphere 8.5.5.11及以上版本才完全支持Java 8,补丁没装也可能导致奇怪的兼容性问题。
内容的提问来源于stack exchange,提问作者nani1987
相关产品推荐
相关产品推荐

