Connecting to Cassandra with Java driver, getting error "local DC must be explicitly set"

Viewed 81

I try to create a connection using given paramters.

CqlSessionBuilder builder = CqlSession.builder();
        int port = 9042;
        for ( String host : hosts ){
            int idx = host.indexOf(":");
            if ( idx > 0 ){
                port = Integer.parseInt( host.substring( idx +1).trim() );
                host = host.substring( 0, idx ).trim();
            }
            builder.addContactPoint( new InetSocketAddress( host, port ) );
            if (sslEnabled) {
                //builder.withSSL();
            }
        }
        if ( dataCenter != null ) builder.withLocalDatacenter( dataCenter );
        if ( userName != null && !userName.isEmpty() && password != null ) {
            builder.withAuthCredentials(userName, password);
        }
        return builder.build();

When connecting, I get this error:

Since you provided explicit contact points, the local DC must be explicitly set.

There is a builder.withLocalDatacenter() in the code.

What could be wrong?

2 Answers

One thing I see, is that you're checking dataCenter for null, but you're not checking if it's empty. So if dataCenter was equal to "" (an empty string) it would get past the check for null, but still not apply a valid dataCenter. Therefore, it's considered a better practice to validate strings in Java like this, instead:

if ( dataCenter != null && !dataCenter.isEmpty() ) {
    builder.withLocalDatacenter( dataCenter );
}

But I think the core problem here, is that dataCenter isn't getting a value. I'd verify that.

Based on the code snippet you provided, dataCenter is undefined and hasn't been initialised. As a result the test condition doesn't get satisfied so withLocalDatacenter() doesn't get called.

In any case as the error message states, you need to explicitly tell the driver the name of the local DC so checking whether dataCenter is null or empty is bad practice.

Instead, you should always specify the data centre local to your app. For example:

datastax-java-driver {
  basic.load-balancing-policy {
    local-datacenter = DC1
  }
}

Of course when you're programatically building the session configuration, always make a call to withLocalDatacenter(), for example:

CqlSession session = CqlSession.builder()
    .withLocalDatacenter("DC1")
    .build();

For details, see Load balancing in the Java driver.

Related