Issue
I am trying to integrate shedlock in my spring boot project using a cassandra db.
But I am getting the below error on application startup.
2022-11-18 17:35:29,162 [main] ERRR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lockProvider'
Caused by: java.lang.NullPointerException: table can not be null
at java.base/java.util.Objects.requireNonNull(Objects.java:233)
at net.javacrumbs.shedlock.provider.cassandra.CassandraLockProvider$Configuration.<init>(CassandraLockProvider.java:69)
at net.javacrumbs.shedlock.provider.cassandra.CassandraLockProvider$Configuration$Builder.build(CassandraLockProvider.java:157)
application.yml file
server:
port: 8080
data:
cassandra:
port: ${CASSANDRA_PORT:9042}
username: ${CASSANDRA_USERNAME:cassandra}
password: ${CASSANDRA_PASSWORD:cassandra}
keyspace-name: ${CASSANDRA_KEYSPACE_NAME:my_keyspace}
schema-action: recreate
local-datacenter: ${CASSANDRA_LOCAL_DATACENTER:datacenter123}
contact-points: ${CASSANDRA_HOST:localhost}
Configuration class
import com.datastax.oss.driver.api.core.CqlSession;
import net.javacrumbs.shedlock.provider.cassandra.CassandraLockProvider;
import net.javacrumbs.shedlock.provider.cassandra.CassandraLockProvider.Configuration;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
@org.springframework.context.annotation.Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "10m")
public class MyAppSchedulerConfiguration {
@Bean
public CassandraLockProvider lockProvider(CqlSession cqlSession) {
return new CassandraLockProvider(Configuration.builder().withCqlSession(cqlSession).build());
}
}
pom.xml file
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<shedlock.version>4.42.0</shedlock.version>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>${shedlock.version}</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-cassandra</artifactId>
<version>${shedlock.version}</version>
</dependency>
Cassandra script executed
CREATE KEYSPACE shedlock with replication={'class':'SimpleStrategy', 'replication_factor':1} and durable_writes=true;
CREATE TABLE shedlock.lock (name text PRIMARY KEY, lockUntil timestamp, lockedAt timestamp, lockedBy text);
I have verified via cqlsh that the lock table is created in cassandra.
The problem in my opinion so far is that the CqlSession bean is not available due to some reason and should have been.
I have tried the configurations as mentioned in the official documentation page.
I have tried downgrading versions of springboot and shedlock but of no use. **Springboot **version change 2.5.x (same error) 2.2.13.RELEASE (same error) 2.3.x (same error)
Solution
I think you have to specify tableName like this
@Bean
public CassandraLockProvider lockProvider(CqlSession cqlSession) {
return new CassandraLockProvider(Configuration.builder().withCqlSession(cqlSession).withTableName("lock").build());
}
It seems the default table name is not set when using the Configuration builder.
Answered By - Lukas
Answer Checked By - Cary Denson (JavaFixing Admin)