Search code examples
javacassandrahazelcast

Deploying Cassandra driver using Hazelcast client deployment option giving following error


I am trying to use MapStore backed by Cassandra. For that pushing those MapStore and MapLoader implementations to Hazelcast member using ClientUserCodeDeploymentConfig as follows

public class CassandraMapStoreFactory implements MapStoreFactory<String, Long> {

    @Override
    public MapLoader<String, Long> newMapStore(String mapName, Properties properties) {
        return new CassandraPersistence(buildSession());
    }

    private Session buildSession() {
        try {
            ConsistencyLevel consistencyLevel = ConsistencyLevel.LOCAL_QUORUM;

            PoolingOptions poolingOptions = new PoolingOptions()
                    .setMaxRequestsPerConnection(HostDistance.LOCAL, 1024)
                    .setMaxRequestsPerConnection(HostDistance.REMOTE, 256);

            Cluster cluster = Cluster.builder()
                    .addContactPoints("15.207.180.45")
                    .withQueryOptions(new QueryOptions().setConsistencyLevel(consistencyLevel))
                    .withSocketOptions(new SocketOptions().setReadTimeoutMillis(12000))
                    .withPoolingOptions(poolingOptions)
                    .withSpeculativeExecutionPolicy(new ConstantSpeculativeExecutionPolicy(10000, 2))
                    .build();
            return cluster.connect("sample");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

And following is the code to push client code to Hazelcast member/server

public static void main(String[] args) {
        ClientConfig config = new ClientConfig();
        ClientUserCodeDeploymentConfig codeDeploymentConfig = new ClientUserCodeDeploymentConfig().setEnabled(true)
                .addClass(CounterEntryProcessor.class).addClass(CassandraMapStoreFactory.class).addClass(CassandraPersistence.class).addJar("cassandra-driver-core-3.1.2.jar");
        config.setUserCodeDeploymentConfig(codeDeploymentConfig);
        config.setClassLoader(MapIdGeneratorWithClient.class.getClassLoader());

        HazelcastInstance hazelcastInstance = HazelcastClient.newHazelcastClient(config);

        // map processing logic
        
        hazelcastInstance.shutdown();
    }

I see the following issue while initializing CassandraMapStoreFactory. It seems issue with Java 9 Modules features and I am using Java 11. Please guide me on what to do to make use of Cassandra driver in Hazelcast map store in the client/server deployment approach

Caused by: java.lang.IllegalAccessError: class com.datastax.driver.core.AbstractAddressableByIndexData cannot access its abstract superclass com.datastax.driver.core.AbstractGettableByIndexData (com.datastax.driver.core.AbstractAddressableByIndexData is in unnamed module of loader com.hazelcast.internal.usercodedeployment.impl.ClassSource @3614246c; com.datastax.driver.core.AbstractGettableByIndexData is in unnamed module of loader com.hazelcast.internal.usercodedeployment.impl.ClassSource @4890c0d0)

Solution

  • Unless you absolutely need to be dynamic, I'd advise against using user code deployment. The nominal path is to actually start the member with the necessary classes on its class path.

    Adding the JAR is just as easy as setting the CLASSPATH environment variable. It will work with both the ZIP distribution and the Docker image.

    Here's an extract of a docker-compose.yaml file that showcases it:

    version: '3'
    services:
      server:
        container_name: hz
        image: hazelcast/hazelcast:4.0
        ports:
          - 5701:5701
        volumes:
          - /Users/nico/.m2/repository:/opt/hazelcast/classpath
        environment:
          - CLASSPATH=/opt/hazelcast/classpath/org/json/json/20200518/json-20200518.jar:/opt/hazelcast/classpath/org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.jar:/opt/hazelcast/classpath/com/github/kittinunf/fuel/fuel/2.2.3/fuel-2.2.3.jar:/opt/hazelcast/classpath/com/github/kittinunf/result/result/3.0.1/result-3.0.1.jar