0

I am using Elasticsearch Rest Client v5.5.3 to execute Elasticsearch queries in a Java application. It always throws java.lang.ArrayStoreException. First I suspect frequency of query execution since application intensively executes queries but it throws exception very first query. Second I update some dependencies like Apache HttpCore.jar which Elasticsearch rest client uses. But either way I could not figure out how to solve it still throws exception. Stack trace is below;

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/:?]

The method executes queries;

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;
    }
hrn
  • 111
  • 1
  • 1
  • 12

1 Answers1

3

Problem description

The problem root cause is "JAR Hell" due to conflicts httpclient-4.5.2 and flux-core-1.1.0. I don't know why but flux-core-1.1.0 jar contains inside full httpclient codebase version 4.3.3 which is not compatible with 4.5.2.

What is ArrayStoreException, Javadoc quote:

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);

In version httpclient-4.3.3 RFC2965VersionAttributeHandler looks like

@Immutable
public class RFC2965VersionAttributeHandler implements CookieAttributeHandler {

In version httpclient-4.5.2 RFC2965VersionAttributeHandler looks like

@Immutable
public class RFC2965VersionAttributeHandler implements CommonCookieAttributeHandler {

And the problem in DefaultCookieSpec which tries to invoke constructor of RFC2965Spec of version 4.5.2 with RFC2965VersionAttributeHandler from 4.3.3, which in not implements CommonCookieAttributeHandler:

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

Solution

The most probably reason of "JAR Hell" - your pom.xml (or gradle) has dependency for httpclient-4.5.2. You should remove it from dependencies or downgrade to 4.3.3 version. Also your pom.xml may have dependency for httpasyncclient-4.1.2 - in this case you also could remove it from dependencies or downgrade to 4.0.x version. At worth your project could have transitive dependency for httpclient or httpasyncclient - in such case you need to find and fix it.

Yuriy Alevohin
  • 941
  • 7
  • 18
  • There is also another solution if for some reason you can't change dependency or it is not convenient to do. You can have the same library in two different versions in your code if you use [shading](http://maven.apache.org/plugins/maven-shade-plugin/) or [fat-jars](https://forgegradle.readthedocs.io/en/latest/user-guide/shading/) on problematic dependency. Probably overkill in this case, but it's still worth to mention it as one of the solutions. – slawek Apr 18 '18 at 12:47
  • Thanks for answer. Whatever I did to exclude dependencies from flux-core it did not work. I used exclusion for dependency tag and used shade to exclude package from dependency. None of them worked – hrn Apr 19 '18 at 08:16
  • You cannot exclude something from `flux-core` because it's a single jar containing classes from `httpclient`. Try to find out which components also has `httpclient` as dependency. F.e. with `mvn dependency:tree -Dverbose -Dincludes=httpclient` for Maven. – Yuriy Alevohin Apr 19 '18 at 08:50
  • Elasticsearch rest client (v5.5.3) has httpclient dependency. I think I should find a way to exclude from apache storm flux-core since I cannot downgrade version of Elasticsearch rest client. – hrn Apr 19 '18 at 10:23