CacheBuilder中的java NoSuchMethodError(checkState)
我创建了一个基于CacheBuilder的缓存,它包含了一些有用的东西,在几乎任何Java项目中都非常方便,包括用于不可变集合、函数编程、I/O等的库
LoadingCache<String, Byte[]> companyDevicesCache =
CacheBuilder.newBuilder()
.maximumSize(1000) // maximum 100 records can be cached
.expireAfterAccess(24, TimeUnit.HOURS) // cache will expire after 30 minutes of access
.build(new CacheLoader<String, Byte[]>(){ // build the cacheloader
@Override
public Byte[] load(String companyId) throws Exception {
//make the expensive call
return getFromServletContext (companyId);
}
});
我也试过了
CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(1000)
.build(new CacheLoader<String, List<String>>() {
@Override
public List<String> load(String queryKey) throws Exception {
return null;
}
});
而且
CacheLoader loader = new CacheLoader()
{
public String load(String key) throws Exception
{
return null;
}
@Override
public Object load(Object arg0) throws Exception {
// TODO Auto-generated method stub
return null;
}
};
LoadingCache<String, String> persons = CacheBuilder.newBuilder()
.initialCapacity(30)
.maximumSize(40)
.recordStats()
.build(loader);
及
final LoadingCache<String, Optional<Product>> cache =
CacheBuilder.newBuilder()
.expireAfterWrite(1, TimeUnit.DAYS)
.refreshAfterWrite(1, TimeUnit.SECONDS)
.build( new CacheLoader<String, Optional<Product>>() {
@Override
public Optional<Product> load( String productId ) throws Exception {
return null;
}
}
);
但当我初始化CacheBuilder时,出现了以下错误:
]] Root cause of ServletException.
java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkState(ZLjava/lang/String;J)V
at com.google.common.cache.CacheBuilder.maximumSize(CacheBuilder.java:409)
这是库的版本:guava-20.0-rc1.jar
这里是ear中包含的LIB
我还试图替换这个库guava-19.0.jar
,但后来我
]] Root cause of ServletException.
java.lang.IncompatibleClassChangeError: Found interface com.google.common.base.Equivalence, but class was expected
at com.google.common.cache.LocalCache$Strength$1.defaultEquivalence(LocalCache.java:393)
at com.google.common.cache.CacheBuilder.getKeyEquivalence(CacheBuilder.java:297)
at com.google.common.cache.LocalCache.<init>(LocalCache.java:246)
at com.google.common.cache.LocalCache$LocalLoadingCache.<init>(LocalCache.java:4868)
at com.google.common.cache.CacheBuilder.build(CacheBuilder.java:786)
# 1 楼答案
看起来类路径上有多个版本的
com.google.common.base.Preconditions
类(可能来自一个非常古老的google collections jar?),或者一个损坏的罐子未找到的method overload已被added in Guava 20.0:
根据
NoSuchMethodError
中的签名:通过在调用
CacheBuilder.maximumSize()
之前添加以下代码,可以找到类定义的来源:您将获得jar的URL
我已经从Maven Central下载了
guava-20.0-rc1.jar
,提取了它的内容,并使用javap
检查了Preconditions.class
的内容,方法确实存在:在ant代码段中,包含多个通配符,例如:
其中可能有一个额外版本的番石榴,特别是考虑到切换到Guava-19.0时出现的另一个错误:
Equivalence
在9.0之前是一个interface,在10.0之前在2011中更改为一个class