0

I am trying to use ehcache.

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
      public JCacheCacheManager jCacheCacheManager() throws IOException {
        return new JCacheCacheManager(cacheManager());
      }

      @Bean(destroyMethod = "close")
      public javax.cache.CacheManager cacheManager() throws IOException {
        XmlConfiguration xmlConfig = new XmlConfiguration(new ClassPathResource("ehcache.xml").getURL());
        EhcacheCachingProvider provider = (EhcacheCachingProvider) Caching.getCachingProvider();
        return provider.getCacheManager(provider.getDefaultURI(), xmlConfig);

      }
    }
@Service
public class AvengersService {


    @Cacheable(cacheNames="avengers" , key="#id")
    public List<String> getAvengers(String id) {
        System.out.println("Loading avengers");
        return Arrays.asList(id.toString(),"Captain America", "Hulk", "Iron Man", "Thor");
    }

}

@SpringBootApplication
@ComponentScan
public class DemoApplication   {

    @Autowired
    private CacheManager cacheManager;

    @Autowired
    private AvengersService avengersService;

    public static void main(String[] args) {


          //list all the caching provider
        Iterator<CachingProvider> iterator = Caching.getCachingProviders(Caching.getDefaultClassLoader()).iterator();
        while(iterator.hasNext()) {
            CachingProvider provider = iterator.next();
            System.out.println(provider);
            if ((provider instanceof HazelcastCachingProvider)) {
                iterator.remove();
            }
        }

        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {

            JCacheCache cache = (JCacheCache) cacheManager
                    .getCache("avengers");

        for(Long i=1L;i<50001;i++) {
            List<String> t=avengersService.getAvengers(String.valueOf(i)+"a");
        cache.put(String.valueOf(i)+"a", avengersService.getAvengers(String.valueOf(i)+"a"));
        }
        System.out.println();

        Cache<Object, Object>    e= ( cache.getNativeCache());
        Iterator<Cache.Entry<Object, Object>> iterator = ( e).iterator();
        int count=1;
        while (iterator.hasNext()) {
            Cache.Entry<Object, Object> t = iterator.next();
            count++;
            System.out.println("key :" + t.getKey() + " value " + t.getValue());
        }


        System.out.println(count);

        final MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();

        final Set<ObjectInstance> cacheBeans = beanServer.queryMBeans(ObjectName.getInstance("javax.cache:type=CacheStatistics,CacheManager=*,Cache=*"), null);

        for ( ObjectInstance cacheBean : cacheBeans ) {
            final CacheStatisticsMXBean cacheStatisticsMXBean = MBeanServerInvocationHandler.newProxyInstance(beanServer, cacheBean.getObjectName(), CacheStatisticsMXBean.class, false);

            System.out.println("Gets: " + cacheStatisticsMXBean.getCacheGets());
            System.out.println("Hits: " + cacheStatisticsMXBean.getCacheHits());
            System.out.println("Misses: " + cacheStatisticsMXBean.getCacheMisses());
            System.out.println("Removals: " + cacheStatisticsMXBean.getCacheRemovals());
            System.out.println("Evictions: " + cacheStatisticsMXBean.getCacheEvictions());
            System.out.println("Avg Get Time: " + cacheStatisticsMXBean.getAverageGetTime());
            System.out.println("Avg Put Time: " + cacheStatisticsMXBean.getAveragePutTime());
            System.out.println("Avg Remove Time: " + cacheStatisticsMXBean.getAverageRemoveTime());
        }
        };
    }

}
public class MyCacheEntryListener<K, V> implements CacheEventListener<K, V>, Serializable {

    @Override
    public void onEvent(CacheEvent<? extends K, ? extends V> event) {
        // TODO Auto-generated method stub

        if (EventType.UPDATED == event.getType()) {
            System.out.println("Received a " + event);
        }
    }

}
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.ehcache.org/v3"
    xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
    xsi:schemaLocation="
            http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
            http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">

 <service>
      <jsr107:defaults enable-management="true" enable-statistics="true"/>
  </service>
    <cache alias="avengers">
        <key-type>java.lang.String</key-type>
        <value-type>java.util.Arrays$ArrayList</value-type>
        <expiry>
             <none/>
        </expiry>
 <listeners>
            <listener>
                <class>com.example.demo.MyCacheEntryListener</class>
                <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
                <event-ordering-mode>UNORDERED</event-ordering-mode>
                <events-to-fire-on>UPDATED</events-to-fire-on>
            </listener>
        </listeners>
        <resources>
            <heap unit="entries">2</heap>
            <offheap unit="MB">10</offheap>
        </resources>
    </cache>

</config>
spring.cache.jcache.config=classpath:ehcache.xml

Blockquote

While starting my appilication its prints 2 cache provider.

HazelcastCachingProvider{delegate=HazelcastServerCachingProvider{hazelcastInstance=null}} org.ehcache.jsr107.EhcacheCachingProvider@1f57539

  1. Why its initialising the 2 cache provider?
  2. if its default how can I disable these?
  3. I have added 50000 object in the cache but while iterating it i am only getting "36406" object why?
deepak PATRA
  • 91
  • 1
  • 1
  • 7

1 Answers1

1

There are a lot of moving parts here. You don't need to configure the CacheManager, it is done automatically with the spring.cache.jcache.config property. Remove the 2 @Bean methods.

If you need to access the javax.cache.CacheManager, you can inject JCacheCacheManager and it'll give you access to the native one it wraps.

There are several JSR107 implementations on the classpath so that API call gives you what's available, this is nothing Spring Boot has control over.

Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89
  • Thanks a lot, @Stephane Nicoll for the immediate response. the count was not correct because I have configurated less memory . – deepak PATRA Dec 15 '19 at 05:40