This rule raises an issue when a class implements the cache key generator interface but does not provide a mechanism for the caching framework to instantiate it, either through a default constructor or through registration with the dependency injection container.

In Java, this specifically refers to the CacheKeyGenerator interface and CDI (Contexts and Dependency Injection) bean annotations.

Why is this an issue?

When implementing a custom cache key generator interface in the framework, the caching subsystem must be able to create instances of your implementation class. The framework supports two instantiation mechanisms:

When a cache key generator implementation lacks both of these, the framework cannot instantiate it. This prevents the cache from generating keys properly.

The problem typically manifests when developers try to pass configuration or dependencies through constructor parameters without providing an alternative instantiation path. While the intention may be to configure the key generator, this approach breaks the framework’s ability to create instances.

What happens at runtime

When the cache attempts to use your key generator, the framework will try to instantiate it. Without a valid instantiation mechanism:

This failure occurs during actual cache operations, not at application startup, making it harder to detect during development.

What is the potential impact?

When custom cache key generator implementations cannot be instantiated, the application will fail at runtime when cache operations attempt to use the key generator. This breaks caching functionality for any methods that reference the problematic generator.

Users will experience:

Since the failure happens at runtime rather than build time, it may not be caught during development and could reach production environments.

How to fix it in Quarkus

Convert your CacheKeyGenerator implementation into a CDI bean by adding a scope annotation like @ApplicationScoped or @Dependent. This allows you to inject dependencies normally while letting Quarkus manage the instance lifecycle.

Code examples

Noncompliant code example

public class CustomKeyGen implements CacheKeyGenerator {
    private final ConfigService configService;

    public CustomKeyGen(ConfigService configService) { // Noncompliant
        this.configService = configService;
    }

    @Override
    public Object generate(Method method, Object... methodParams) {
        String prefix = configService.getPrefix();
        return new CompositeCacheKey(prefix, methodParams[0]);
    }
}

Compliant solution

@ApplicationScoped
public class CustomKeyGen implements CacheKeyGenerator {
    private final ConfigService configService;

    CustomKeyGen(ConfigService configService) {
        this.configService = configService;
    }

    @Override
    public Object generate(Method method, Object... methodParams) {
        String prefix = configService.getPrefix();
        return new CompositeCacheKey(prefix, methodParams[0]);
    }
}

Resources

Documentation

Related rules