# JetCache Agent Instructions ## Project Overview JetCache is a Java cache abstraction library (groupId `com.alicp.jetcache`) providing uniform API over Redis (Jedis/Lettuce/Spring Data/Redisson), Caffeine, and LinkedHashMap. Supports annotations (`@Cached`, `@CacheUpdate`, `@CacheInvalidate`) and programmatic `Cache` API with two-level caching, TTL, auto-refresh, and distributed lock. - Source/target: Java 17 (compiled with `-parameters`, enforcer requires JDK 17+) - CI JDK: 17 (Temurin) - Version: 2.8.x-SNAPSHOT ## Module Structure ``` jetcache-anno-api/ Annotations and constants only (no dependencies) jetcache-core/ Core Cache API, CacheManager, embedded/external cache implementations jetcache-anno/ Spring AOP-based annotation processing (depends on core) jetcache-support/ Redis driver adapters: jetcache-redis/ Jedis 7.x jetcache-redis-lettuce/ Lettuce jetcache-redis-springdata/ Spring Data Redis 4.x (uses Lettuce, not Jedis) jetcache-redisson/ Redisson 4.x jetcache-starter/ Spring Boot autoconfigure and starters: jetcache-autoconfigure/ Pulls all support modules (optional) jetcache-starter-redis/ etc. jetcache-test/ All tests live here (aggregates all modules); uses JaCoCo for coverage jetcache-parent/ Shared build config, PMD (Alibaba p3c rules), surefire settings jetcache-bom/ Bill of Materials, dependency version management samples/ NOT part of root build (separate pom, different groupId) ``` Dependency chain: `anno-api <- core <- anno <- autoconfigure`, `core <- support/* <- starter/*`. ## Build & Test Commands ```bash # Full build (no tests) mvn -DskipTests clean install # Run all tests (requires Redis, see below) mvn clean test # Run a single test class mvn -pl jetcache-test test -Dtest=CacheHandlerTest # Run a single test method mvn -pl jetcache-test test -Dtest=CacheHandlerTest#testExpressionEvaluator ``` Surefire includes: `**/Test*.java`, `**/*Test.java`, `**/*Tests.java`, `**/*TestCase.java`. Surefire excludes `@Tag("slow")` tests (currently none tagged). ### macOS: Tests Needing Redis The `docker-compose.yml` uses `network_mode: "host"`, which **does not work on macOS Docker**. Redis cluster tests skip themselves on Mac/Windows (runtime check in `RedisLettuceCacheTest.checkOS()`). To run the full suite on macOS, use the Docker-in-Docker approach from `Building.txt`: ```bash docker compose up -d # Linux only # macOS alternative: docker run -it --rm --network host -v $HOME/.m2:/root/.m2 -v $(pwd):/usr/src/mymaven -w /usr/src/mymaven maven:3.9-eclipse-temurin-17 mvn clean test ``` ### Quick local Redis for partial testing (Windows/Mac) ```bash docker run --rm -it -p 6379-6381:6379-6381 -p 26379-26381:26379-26381 areyouok/redis-sentinel ``` This gives standalone + sentinel but **not** cluster mode. Cluster tests will skip. ## Verification ```bash mvn clean test # after `docker compose up` on Linux mvn verify # also runs PMD check (Alibaba p3c ruleset) ``` ## Conventions - JUnit Jupiter only (JUnit 4 removed; no vintage engine). JUnit BOM version: 6.x - Test dependencies: JUnit Jupiter 6.x, Mockito 5.x, Spring Test - PMD uses Alibaba p3c rules (`p3c-pmd:1.3.6`) during `verify` phase - The `-parameters` javac flag is required for SpEL annotation key expressions to work (also must be set in IDE settings, not just pom) - `samples/` has its own build chain with its own version of jetcache; it is not a module of the main build ## Test Caveats - Tests can be flaky on busy machines: many tests use short `sleep()` to verify TTL/expiry behavior, so GC pauses or high load can cause false failures - Full test suite takes a few minutes to run - Tests needing Redis (e.g. `RedisCacheTest`, `RedisLettuceCacheTest`, `RedissonCacheTest`, starter tests) will fail or skip without a running Redis - Redis cluster tests auto-skip on Mac/Windows via `RedisLettuceCacheTest.checkOS()` — only standalone and sentinel tests work there ## Compatibility Notes (see `docs/EN/Compatibility.md`) - Spring/Spring Boot version support varies by jetcache version; current (2.8.0) BOM defaults to Spring Framework 7.0.7 / Spring Boot 4.0.6 / Spring Data Redis 4.0.5 / SLF4J 2.x, but Spring 6.x / Spring Boot 3.x (also Java 17+) is also supported by adjusting BOM properties - `jetcache-redis` (Jedis 7.x) and `jetcache-redis-springdata` (Lettuce) use different Redis clients; `jetcache-redis` uses Jedis 7.x which may conflict with other Jedis versions on classpath - Since 2.8.0: fastjson1 is **removed**; the `FASTJSON` keyConvertor now uses fastjson2 internally. Default keyConvertor is `fastjson2` - Since 2.8.0: kryo4 is **dropped**. Both `KRYO` and `KRYO5` constants now use kryo5 implementation internally (`com.esotericsoftware:kryo` is 5.6.2, same as `com.esotericsoftware.kryo:kryo5`). Old kryo4 serialized data is **not compatible** with kryo5 - Since 2.8.0: Spring XML namespace support (``) is **removed** - Since 2.8.0: **Deserialization filter is enabled by default** — a breaking change. Cached values containing custom classes not in the default allow list will fail to deserialize. Add `decodeFilterAllowPatterns` (e.g. `com.yourcompany.`) or set `decodeFilterEnabled: false` to restore old behavior. See `docs/EN/Config.md` for default allow list - Since 2.8.0: `JACKSON3` added as valueEncoder/valueDecoder and keyConvertor option (uses `tools.jackson` 3.x) - `areaInCacheName` default changed to `false` in 2.7 (was `true` in 2.6 and earlier); since 2.8.0 this is also `false` - JSON serializers (fastjson2/jackson/jackson3) are **not registered by default** as valueEncoder/valueDecoder due to type-safety concerns with `Object` fields. Only `java` and `kryo`/`kryo5` are registered - `@Cached` uses Spring AOP (proxy-based); self-invocation within the same class bypasses the cache ## Key Convertor / Value Encoder-Decoder Choices (2.8) - keyConvertor: `fastjson2` (default) / `fastjson` (same as fastjson2) / `jackson` / `jackson3` / `none` (local only) - valueEncoder/valueDecoder: `java` (default) / `kryo` (kryo5 impl) / `kryo5` (kryo5 impl). `fastjson2` / `jackson` / `jackson3` available but not registered by default ## Code Reading Guide (see `docs/CN/DevNote.md`) Key `Cache` interface implementations: - `RedisCache` / `RedisLettuceCache` / `RedisSpringDataCache` / `RedissonCache`: external Redis backends - `CaffeineCache` / `LinkedHashMapCache`: in-memory - `LoadingCache`: decorator adding auto-load via `CacheLoader` - `RefreshCache`: decorator adding auto-refresh - `MultiLevelCache`: multi-level (supports N levels, annotation config only uses 2) Annotation processing entry points: `EnableMethodCache`, `EnableCreateCacheAnnotation` (in `jetcache-anno`)