You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EhCache v3.5.2实现堆内缓存时遇‘无序列化器’错误求助

解决EhCache 3.5.2堆内缓存「No serializer found」错误

这个问题我之前在项目里也踩过坑——别以为堆内缓存就不用序列化,EhCache 3.x的堆内 tier 虽然把对象存在JVM堆中,但内部在处理缓存的一些核心逻辑(比如状态同步、统计或者持久化前的准备)时,依然需要序列化支持。你的MyObj类既没实现标准序列化接口,也没配置自定义序列化器,所以就触发了这个错误。

下面给你两种可行的解决办法:

方法一:让自定义对象实现Serializable接口(快速解决)

这是最直接的方案,让你的MyObj类实现Java标准的Serializable接口,EhCache会自动使用Java序列化来处理对象:

public class TestEhCache { 
    public static class MyObj implements Serializable { 
        // 推荐添加序列化ID,避免类结构变化后出现序列化兼容问题
        private static final long serialVersionUID = 1L;
        
        String message; 
        public MyObj(String message) { 
            this.message = message; 
        } 
    } 

    @Test 
    public void testDebugLogs() { 
        CacheManager cacheManager; 
        cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(); 
        cacheManager.init(); 
        
        // 构建缓存配置,现在MyObj可序列化,不会报错
        Cache<String, MyObj> myCache = cacheManager.createCache("myCache", 
            CacheConfigurationBuilder.newCacheConfigurationBuilder(
                String.class, MyObj.class, 
                ResourcePoolsBuilder.heap(100) // 指定堆内缓存大小
            )
        );
        
        // 测试存取值
        myCache.put("key1", new MyObj("Hello EhCache!"));
        System.out.println(myCache.get("key1").message);
        
        cacheManager.close();
    }
}

方法二:配置自定义序列化器(灵活扩展)

如果不想用Java序列化(比如追求更高性能、不想暴露序列化ID),可以给EhCache配置自定义的序列化器。比如用Jackson的JSON序列化,或者自己实现Serializer接口:

步骤1:实现自定义序列化器

public class MyObjSerializer implements Serializer<MyObj> {
    @Override
    public ByteBuffer serialize(MyObj object) throws SerializerException {
        // 这里用Jackson将对象转为JSON字节数组
        try {
            ObjectMapper mapper = new ObjectMapper();
            byte[] bytes = mapper.writeValueAsBytes(object);
            return ByteBuffer.wrap(bytes);
        } catch (JsonProcessingException e) {
            throw new SerializerException("Failed to serialize MyObj", e);
        }
    }

    @Override
    public MyObj read(ByteBuffer binary) throws ClassNotFoundException, SerializerException {
        // 反序列化JSON字节数组为MyObj
        try {
            ObjectMapper mapper = new ObjectMapper();
            byte[] bytes = new byte[binary.remaining()];
            binary.get(bytes);
            return mapper.readValue(bytes, MyObj.class);
        } catch (IOException e) {
            throw new SerializerException("Failed to deserialize MyObj", e);
        }
    }

    @Override
    public boolean equals(Object object) {
        return object instanceof MyObjSerializer;
    }
}

步骤2:在缓存配置中指定序列化器

@Test 
public void testDebugLogs() { 
    CacheManager cacheManager; 
    cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(); 
    cacheManager.init(); 
    
    Cache<String, MyObj> myCache = cacheManager.createCache("myCache", 
        CacheConfigurationBuilder.newCacheConfigurationBuilder(
            String.class, MyObj.class, 
            ResourcePoolsBuilder.heap(100)
        )
        // 配置自定义序列化器
        .withSerializer(MyObj.class, new MyObjSerializer())
    );
    
    myCache.put("key1", new MyObj("Hello Custom Serializer!"));
    System.out.println(myCache.get("key1").message);
    
    cacheManager.close();
}

注意事项

  • 如果用方法一,记得给序列化类添加serialVersionUID,避免类结构变化后出现反序列化失败的问题。
  • 如果你用的是EhCache的集群功能,序列化会更重要,堆外或磁盘缓存也必须配置序列化。

内容的提问来源于stack exchange,提问作者isvirkina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:50:50