Rules and patterns for implementing cache in a Lutece 8 plugin. AbstractCacheableService, CDI initialization, cache operations, invalidation via CDI events.
View on GitHubskills/lutece-cache/SKILL.md
February 5, 2026
Select agents to install to:
npx add-skill https://github.com/lutece-platform/lutece-dev-plugin-claude/blob/main/skills/lutece-cache/SKILL.md -a claude-code --skill lutece-cacheInstallation paths:
.claude/skills/lutece-cache/# Lutece 8 Cache Implementation
> Before implementing cache, consult `~/.lutece-references/lutece-form-plugin-forms/` — specifically `FormsCacheService.java`.
## Architecture Overview
```
AbstractCacheableService<K, V> (lutece-core, JSR-107 JCache)
↑ extends
MyCacheService (@ApplicationScoped, @PostConstruct initCache)
↓ used by
Home / Service (put, get, remove, resetCache)
↓ invalidated by
CDI Events (@Observes)
```
## Step 1 — Cache Service Class
> **IMPORTANT:** The `put()`/`get()`/`remove()` methods inherited from `AbstractCacheableService` delegate directly to `_cache` without null/closed checks. If the cache is disabled in the datastore (default state), `_cache` is `null` and these methods throw `NullPointerException`. You **MUST** override them with defensive guards.
```java
import javax.cache.CacheException;
import fr.paris.lutece.portal.service.cache.AbstractCacheableService;
import fr.paris.lutece.portal.service.util.AppLogService;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class EntityCacheService extends AbstractCacheableService<String, Object>
{
private static final String CACHE_NAME = "myplugin.entityCacheService";
@PostConstruct
public void init( )
{
initCache( CACHE_NAME, String.class, Object.class );
}
@Override
public String getName( )
{
return CACHE_NAME;
}
@Override
public void put( String key, Object value )
{
if ( isCacheEnable( ) && isCacheAvailable( ) )
{
try
{
super.put( key, value );
}
catch( CacheException | IllegalStateException e )
{
AppLogService.error( "EntityCacheService : error putting key {} in cache", key, e );
}
}
}
@Override
public Object get( String key )
{
if ( isCacheEnable( ) && isCacheAvailable( ) )
{