我正在使用Elasticsearch Rest Client v5.5.3在Java应用程序中执行Elasticsearch查询。它总是抛出java.lang.ArrayStoreException。首先,我怀疑查询执行的频率,因为应用程序密集执行查询,但它在第一个查询时抛出异常。其次,我更新了一些依赖项,例如Elasticsearch rest客户端使用的Apache HttpCore.jar这些依赖项。但无论哪种方式,我都无法弄清楚如何解决它仍然会引发异常。堆栈跟踪如下;
java.lang.ArrayStoreException: org.apache.http.impl.cookie.RFC2965VersionAttributeHandler
at org.apache.http.impl.cookie.DefaultCookieSpecProvider.create(DefaultCookieSpecProvider.java:92) ~[httpclient-4.5.2.jar:4.5.2]
at org.apache.http.client.protocol.RequestAddCookies.process(RequestAddCookies.java:152) ~[flux-core-1.1.0.jar:1.1.0]
at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:132) ~[flux-core-1.1.0.jar:1.1.0]
at org.apache.http.impl.nio.client.MainClientExec.prepareRequest(MainClientExec.java:520) ~[httpasyncclient-4.1.2.jar:4.1.2]
at org.apache.http.impl.nio.client.MainClientExec.prepare(MainClientExec.java:146) ~[httpasyncclient-4.1.2.jar:4.1.2]
at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:124) ~[httpasyncclient-4.1.2.jar:4.1.2]
at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141) ~[httpasyncclient-4.1.2.jar:4.1.2]
at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:343) ~[rest-5.5.3.jar:5.5.3]
at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:325) ~[rest-5.5.3.jar:5.5.3]
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:218) ~[rest-5.5.3.jar:5.5.3]
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:191) ~[rest-5.5.3.jar:5.5.3]
at com.nova.stats.platform.are.batch.rule.ElasticsearchQueryExecutor.execute(ElasticsearchQueryExecutor.java:36) [classes/:?]
该方法执行查询;
public String execute(String query, QueryParameters parameters) throws IOException {
String index = (String) parameters.getParameter(GlobalConfigurations.ElasticsearchConfigurations.ConfigurationFields.INDEX);
String type = (String) parameters.getParameter(GlobalConfigurations.ElasticsearchConfigurations.ConfigurationFields.TYPE);
RestClient restClient = ElasticsearchRestClient.getClient();
HttpEntity entity;
Response response = null;
try {
entity = new NStringEntity(query);
response = restClient.performRequest("GET", "/" + index + "/" + type + "/_search",
Collections.singletonMap("pretty", "true"), entity);
} catch (Exception e) {
logger.error("Could not perform request, query: " + query, e);
}
String responseStr = responseStr = EntityUtils.toString(response.getEntity());
return responseStr;
}
问题描述
问题的根本原因是"JAR地狱",由于冲突httpclient-4.5.2
和flux-core-1.1.0
。我不知道为什么,但flux-core-1.1.0
jar 包含完整的 httpclient 代码库版本 4.3.3,它与 4.5.2 不兼容。
什么是ArrayStoreException
,Javadoc引用:
public class ArrayStoreException 扩展 RuntimeException 抛出到 指示已尝试存储错误类型的 对象到对象数组中。例如,以下代码 生成一个 ArrayStoreException: 对象 x[] = 新字符串 [3]; x[0] = 新整数 (0);
在 httpclient-4.3.3 版本中,RFC2965VersionAttributeHandler
看起来像
@Immutable
public class RFC2965VersionAttributeHandler implements CookieAttributeHandler {
在 httpclient-4.5.2 版本中,RFC2965VersionAttributeHandler
看起来像
@Immutable
public class RFC2965VersionAttributeHandler implements CommonCookieAttributeHandler {
以及DefaultCookieSpec
中试图使用 4.3.3 中的RFC2965VersionAttributeHandler
调用版本 4.5.2RFC2965Spec
的构造函数的问题,它没有实现CommonCookieAttributeHandler
:
RFC2965Spec(final boolean oneHeader,
final CommonCookieAttributeHandler... handlers) {
super(oneHeader, handlers);
}
溶液
"JAR 地狱"最可能的原因 - 您的pom.xml
(或 gradle)对httpclient-4.5.2
有依赖性.应将其从依赖项中删除或降级到4.3.3
版本。此外,您的pom.xml
可能具有httpasyncclient-4.1.2
依赖项 - 在这种情况下,您也可以将其从依赖项中删除或降级到4.0.x
版本。值得,您的项目可能对httpclient
或httpasyncclient
具有传递依赖关系 - 在这种情况下,您需要找到并修复它。