英文:
infinispan MarshallableUserObject marshalling error
问题
我在一个Docker化的Spring Boot应用中遇到了嵌入式Infinispan编组的问题。以下是要翻译的代码部分:
public void incrementSmsSend(String key) {
AdvancedCache<String, DailySms> advancedCache = cacheManager.<String, DailySms>getCache("statistics-cache").getAdvancedCache();
try {
advancedCache.computeIfAbsentAsync("totalSms_" + key, s -> new DailySms(0L, null));
advancedCache.getAdvancedCache().merge("totalSms_" + key, new DailySms(1L, null), (dailySmsInit, dailySms) -> {
if (dailySms.isExpired()) {
logger.debug("init numberDailySms: {}", dailySmsInit.getTotal());
return dailySmsInit;
} else {
dailySms.increment();
}
logger.debug("numberDailySms: {}", dailySms.getTotal());
return dailySms;
});
} catch (Exception e) {
logger.error("Error:", e);
}
}
@Bean
public InfinispanCacheConfigurer cacheConfigurer() {
return manager -> {
final org.infinispan.configuration.cache.Configuration ispnConfig = new ConfigurationBuilder()
.clustering()
.cacheMode(CacheMode.REPL_SYNC).remoteTimeout(1, TimeUnit.SECONDS)
.statistics().enable()
.build();
final org.infinispan.configuration.cache.Configuration ispnStatistics = new ConfigurationBuilder()
.clustering()
.cacheMode(CacheMode.REPL_SYNC).remoteTimeout(1, TimeUnit.SECONDS)
.statistics().enable()
.build();
manager.defineConfiguration("vdc-cache", ispnConfig);
manager.defineConfiguration("statistics-cache", ispnStatistics);
};
}
@Bean
public InfinispanGlobalConfigurationCustomizer globalCustomizer() {
return builder -> builder.clusteredDefault().transport().clusterName("vdc-cache-cluster")
.serialization().addContextInitializers(new Bucket4jProtobufContextInitializer(), new ManualSerializationContextInitializer())
.whiteList().addClasses(Tps.class);
}
以上代码生成了以下异常:
2020-07-30 09:19:09.981 - [vdc-ratelimiter-service] - [async-thread--p2-t5] - WARN [o.i.PERSISTENCE] [] ISPN000559: Cannot marshall 'class org.infinispan.marshall.protostream.impl.MarshallableUserObject'
java.io.NotSerializableException: com.ericsson.vdc.ratelimiter.service.service.StatisticsService
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1193)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:353)
at org.infinispan.commons.marshall.JavaSerializationMarshaller.objectToBuffer(JavaSerializationMarshaller.java:44)
at org.infinispan.commons.marshall.AbstractMarshaller.objectToByteBuffer(AbstractMarshaller.java:70)
...
我使用的是infinispan-spring-boot-starter-embedded版本2.3.1.Final和infinispan版本10.1.8.Final。
英文:
I have problem with embedded infinispan marshalling in a dockerize spring boot application.
This method:
public void incrementSmsSend( String key){
AdvancedCache<String, DailySms> advancedCache=cacheManager.<String, DailySms>getCache("statistics-cache").getAdvancedCache() ;
try {
advancedCache.computeIfAbsentAsync("totalSms_"+key,s -> new DailySms(0L,null));
advancedCache.getAdvancedCache().merge("totalSms_"+key,new DailySms(1L,null),(dailySmsInit, dailySms) -> {
if(dailySms.isExpired()){
logger.debug("init numberDailySms: {}",dailySmsInit.getTotal());
return dailySmsInit;
}else{
dailySms.increment();
}
logger.debug("numberDailySms: {}",dailySms.getTotal());
return dailySms;
});
}catch (Exception e){
logger.error("Error:",e);
}
}
With this config:
@Bean
public InfinispanCacheConfigurer cacheConfigurer() {
return manager -> {
final org.infinispan.configuration.cache.Configuration ispnConfig = new ConfigurationBuilder()
.clustering()
.cacheMode(CacheMode.REPL_SYNC).remoteTimeout(1,TimeUnit.SECONDS)
.statistics().enable()
.build();
final org.infinispan.configuration.cache.Configuration ispnStatistics = new ConfigurationBuilder()
.clustering()
.cacheMode(CacheMode.REPL_SYNC).remoteTimeout(1,TimeUnit.SECONDS)
.statistics().enable()//.transaction().transactionMode(TransactionMode.TRANSACTIONAL)
.build();
manager.defineConfiguration("vdc-cache", ispnConfig);
manager.defineConfiguration("statistics-cache", ispnStatistics);
};
}
@Bean
public InfinispanGlobalConfigurationCustomizer globalCustomizer() {
return builder -> builder.clusteredDefault().transport().clusterName("vdc-cache-cluster")
.serialization().addContextInitializers(new Bucket4jProtobufContextInitializer(),new ManualSerializationContextInitializer())
.whiteList().addClasses(Tps.class)
;
}
Generate this exception:
2020-07-30 09:19:09.981 - [vdc-ratelimiter-service] - [async-thread--p2-t5] - WARN [o.i.PERSISTENCE] [] ISPN000559: Cannot marshall 'class org.infinispan.marshall.protostream.impl.MarshallableUserObject'
java.io.NotSerializableException: com.ericsson.vdc.ratelimiter.service.service.StatisticsService
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1193)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:353)
at org.infinispan.commons.marshall.JavaSerializationMarshaller.objectToBuffer(JavaSerializationMarshaller.java:44)
at org.infinispan.commons.marshall.AbstractMarshaller.objectToByteBuffer(AbstractMarshaller.java:70)
...
I use infinispan-spring-boot-starter-embedded version 2.3.1.Final and infinispan version 10.1.8.Final
答案1
得分: 1
我发现了一个问题。
在Spring Bean StatisticsService 方法 incrementSmsSend 中使用了 lambda 表达式,因此 Infinispan 试图序列化所有的 Bean。
我创建了一个 BiFunction,并以以下方式更改了方法:
advancedCache.getAdvancedCache().computeIfPresentAsync("totalSms_" + key, new VdcSerializableFunction())
VdcSerializableFunction 如下:
public class VdcSerializableFunction implements Serializable, BiFunction<String, DailySms, DailySms> {
@Override
public DailySms apply(String s, DailySms dailySms) {
if (dailySms.isExpired()) {
return new DailySms(1L, null);
} else {
dailySms.increment();
}
return dailySms;
}
}
谢谢。
英文:
I found problem.
In the Spring bean StatisticsService method incrementSmsSend used lambda expression so infinispan try to serialized all bean.
I create a BiFunction and change method in this way:
advancedCache.getAdvancedCache().computeIfPresentAsync("totalSms_"+key,new VdcSerializableFunction())
VdcSerializableFunction are:
public class VdcSerializableFunction implements Serializable, BiFunction<String,DailySms,DailySms> {
@Override
public DailySms apply(String s, DailySms dailySms) {
if(dailySms.isExpired()){
return new DailySms(1L,null);
}else{
dailySms.increment();
}
return dailySms;
}
}
Thank You
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论