JDK8环境下HttpClient5报NoSuchMethodError的解决方案咨询
问题解决方案
问题根源
javax.net.ssl.SSLParameters.setApplicationProtocols([Ljava/lang/String;)V 方法是JDK 8u251及后续版本才新增的API,你当前使用的JDK8版本(1.8.0_144/151/191)均未包含该方法,但HttpClient 5.2.1的DefaultClientTlsStrategy类直接调用了这个方法,导致抛出NoSuchMethodError。
可行方案
1. 升级JDK8到u251或更高版本
直接将JDK8升级到8u251及以上版本(比如8u301、8u391),这些版本已经内置了setApplicationProtocols方法,无需修改代码即可解决问题,同时保留JDK8环境。
2. 降级HttpClient5版本到兼容低版本JDK8的分支
HttpClient5从5.3.x开始明确要求JDK8u251+,但5.1.x系列(比如5.1.4)完全兼容JDK8u191及以下版本,不会调用setApplicationProtocols方法。修改依赖配置,将httpclient5和core5版本降级到5.1.4即可。
3. 自定义兼容版TlsStrategy替换默认实现
如果不想修改JDK或依赖版本,可以自定义一个TlsStrategy,通过反射兼容低版本JDK8:
import org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy; import org.apache.hc.client5.http.ssl.ClientTlsStrategy; import org.apache.hc.core5.http.HttpHost; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import java.lang.reflect.Method; public class CompatClientTlsStrategy extends AbstractClientTlsStrategy implements ClientTlsStrategy { public CompatClientTlsStrategy(SSLContext sslContext) { super(sslContext); } @Override protected void applyParameters(SSLParameters sslParams, String[] appProtocols, HttpHost host) { super.applyParameters(sslParams, appProtocols, host); if (appProtocols != null && appProtocols.length > 0) { try { Method setAppProtocolsMethod = SSLParameters.class.getMethod("setApplicationProtocols", String[].class); setAppProtocolsMethod.invoke(sslParams, (Object) appProtocols); } catch (Exception ignore) { // JDK版本过低,跳过应用层协议设置 } } } }
然后在创建HttpAsyncClient时替换默认策略:
CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom() .setTlsStrategy(new CompatClientTlsStrategy(SSLContext.getDefault())) .build();
内容的提问来源于stack exchange,提问作者Swain.Ho
相关产品推荐
相关产品推荐

