0

In my app I have two dependencies, A and B. Dependency A is a library of mine, but dependency B is not.

Both dependencies make use of Caffeine to cache the results in memory.

This is the configuration for Dependency A (mine):

@Configuration
@EnableCaching
public class CaffeineConfiguration {

  @Bean(name="myCacheManager")
  public CacheManager cacheManager() {
      CaffeineCacheManager cacheManager = new CaffeineCacheManager("user");
      cacheManager.setCaffeine(caffeineConfig());
      return cacheManager;
  }

  @Bean(name = "myCaffeineConfig")
  public Caffeine caffeineConfig() {
      return Caffeine.newBuilder()
              .expireAfterAccess(5, TimeUnit.MINUTES);
  }
}

When I run my app and make a request that calls the method annotated with @Cacheable, the following Exception is thrown:

java.lang.IllegalArgumentException: Cannot find cache named 'security.remotePublicKeyCache' for Builder[public java.security.PublicKey com.my.dependencyB.MyClass.getCacheableResult(java.lang.String) throws com.my.dependencyB.CannotProvideKeyException] caches=[security.remotePublicKeyCache] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'

What can I do to avoid having this conflict of Caches?

Thanks

EDIT: I've seen this article from Baeldung https://www.baeldung.com/spring-multiple-cache-managers where he proposes 3 different solutions but the problem I have is with dependencies, not directly in my code and I'm not sure if I can configure that from my side.

Marcos
  • 196
  • 1
  • 16
  • 1
    Have you read the exception? There is no cache with that name, looking at your configuration that is correct as you aren't pre-configuring a cache nor provide any defaults. – M. Deinum Nov 15 '22 at 13:11
  • Yes I did. If I remove dependency A (my library) the exception is not thrown. – Marcos Nov 15 '22 at 13:23
  • 1
    Do both projects configure caching? If so one will override the other. – M. Deinum Nov 15 '22 at 13:25
  • Yes they do, that's what I'm trying to figure out. Maybe using a cache resolver? Or specifying the cachemanager where I define the CacheManager @Bean? – Marcos Nov 15 '22 at 13:39
  • 1
    If they both use Spring Boot you could make yours conditional, like with `@ConditionalOnMissingBean`. Another thing is that if this is Spring Boot you could omit this configuration and use properties instead. – M. Deinum Nov 15 '22 at 13:52
  • Ok, so I could add the `@ConditionalOnMissingBean` on my library `@Cacheable` method. That would force my library to use the already existent CacheManager (from dependency B) but, how could I set the configuration properties for my library (dependency A) if I'm using the other CacheManager? – Marcos Nov 15 '22 at 14:05
  • You don't put it on the `@Cacheable` but on your cachemanager. If you have specific needs you can always use a `BeanPostProcessor` to modify the cachemanager. If yours is a library should it actually bother with configuring the cache? – M. Deinum Nov 15 '22 at 14:07
  • Oh ok. The thing is I need to cache the results somewhere, right? I thought it was appropriate to cache the result inside the library logic because that's where I make a request to an external service. If I don't configure the cache in there, where else would I configure it? – Marcos Nov 15 '22 at 14:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/249632/discussion-between-marcos-and-m-deinum). – Marcos Nov 15 '22 at 14:11
  • Why would you need to configure the cache, that is up to the users of your caching library. You are now also enforcing Caffeine on them for caching, what if they use Redis as a distributed cache? Or just use EhCache? You can make it `@Cacheable` but you can leave the cache configuration to your users. Let them choose the caching implementation. – M. Deinum Nov 15 '22 at 14:12
  • It's not precisely a caching library. It's a library that makes some particular requests to an external service that secures endpoints and also caches the responses. As I want to create new services, I don't want to duplicate the code that makes those requests, that's why I created the library. After creating the library and adding it as a dependency to the main project I started getting the Exception. – Marcos Nov 15 '22 at 14:16
  • I want to be able to use my library with Caffeine without it clashing with other dependencies that also uses Caffeine for caching. – Marcos Nov 15 '22 at 14:18
  • Where do I state you need to duplicate things? The only thing I state is that you shouldn't enforce a library (Caffeine) on users. Make your service cacheable and leave the cache configuration to your users so they can use whatever they want. – M. Deinum Nov 15 '22 at 14:30
  • Sorry if you understood it that way. I was trying to add context. Let's say I do want to go ahead with Caffeine as the cache library for this matter. What can I do? Thanks btw – Marcos Nov 15 '22 at 14:38
  • @M.Deinum so, I removed the Caffeine dependency from my library and of course my test still run using the ConcurrentHashMap cache. You say that I can specify which cache library I can use in my main project? How so? – Marcos Nov 15 '22 at 15:31
  • I suppose that now I can configure dependency A's cache by using the `@Cacheable` value property in my main project, right? – Marcos Nov 15 '22 at 15:33

0 Answers0