Elasticsearch Rest 客户端抛出 java.lang.ArrayStoreException

Elasticsearch Rest Client throws java.lang.ArrayStoreException

我正在使用 Elasticsearch Rest Client v5.5.3 在 Java 应用程序中执行 Elasticsearch 查询。它总是抛出 java.lang.ArrayStoreException。首先,我怀疑查询执行的频率,因为应用程序密集地执行查询,但它在第一个查询时抛出异常。其次,我更新了一些依赖项,例如 Elasticsearch 休息客户端使用的 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;
    }

问题描述

由于 httpclient-4.5.2flux-core-1.1.0 冲突,问题的根本原因是 "JAR Hell"。我不知道为什么,但是 flux-core-1.1.0 jar 包含完整的 httpclient 代码库版本 4.3.3,它与 4.5.2 不兼容。

什么是 ArrayStoreException,Javadoc 引用:

public class ArrayStoreException extends RuntimeException Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects. For example, the following code generates an ArrayStoreException: Object x[] = new String[3]; x[0] = new Integer(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.2 版 RFC2965Spec 的构造函数,但未实现 CommonCookieAttributeHandler :

RFC2965Spec(final boolean oneHeader,
            final CommonCookieAttributeHandler... handlers) {
    super(oneHeader, handlers);
}

解决方案

"JAR Hell" 的最可能原因 - 您的 pom.xml(或 gradle)依赖于 httpclient-4.5.2。您应该将其从依赖项中删除或降级到 4.3.3 版本。此外,您的 pom.xml 可能依赖于 httpasyncclient-4.1.2 - 在这种情况下,您还可以将其从依赖项中删除或降级到 4.0.x 版本。值得您的项目可能具有 httpclienthttpasyncclient 的传递依赖性 - 在这种情况下,您需要找到并修复它。