ClassCastException:datastructures.instances.JClass无法强制转换为java.util.ArrayList

时间:2015-06-08 22:55:52

标签: java class caching classcastexception jcs

我知道有很多关于SO的CCE问题。我已经详细或简要地阅读了他们中的大多数,我找不到适用于我的情况的任何内容。我的确切错误是:

Exception in thread "pool-1-thread-1" java.lang.ClassCastException: datastructures.instances.JClass cannot be cast to java.util.ArrayList

if ((results = mCallsDownstreamCache.get(origin)) == null) {

正如您将在代码中看到的那样,我正在做的是从缓存(ArrayList)中请求HashMap,然后对此做出决定。这里奇怪的行为是datastructures.instances.JClass在生成错误的代码段中引用无法

为了给你一些上下文,我有一个数据库“模型”,它满足来自“控制器”的请求。这些结果存储在模型本地的缓存中,如果存在,模型将返回缓存,因此不必访问数据库。我的缓存元素是Commons' JCS的有效装饰器。

违规行包含在block commentinline comment

public class AnalyzeModel extends Model {

    public final String TAG = getClass().getSimpleName();
    public CacheDecorator<Integer, JClass> mClassCache = new CacheDecorator<Integer, JClass>();
    public CacheDecorator<Integer, JMethod> mMethodCache = new CacheDecorator<Integer, JMethod>();
    public CacheDecorator<Integer, ArrayList<Integer>> mCallsUpstreamCache =
            new CacheDecorator<Integer, ArrayList<Integer>>();
    public CacheDecorator<Integer, ArrayList<Integer>> mCallsDownstreamCache =
            new CacheDecorator<Integer, ArrayList<Integer>>();

    public void close() {
        super.close();
    }

    public Pair<Integer, ArrayList<Integer>> selectCallGraphDownstream(int origin) {
        ArrayList<Integer> results = new ArrayList<Integer>();

        /**
         * This is the offending line
         */
        if ((results = mCallsDownstreamCache.get(origin)) == null) {
        // End error line
            results = new ArrayList<Integer>();
            for (Record r : mQuery.select(
                    mQuery.mQuerier.select(Calls.CALLS.TID)
                            .from(Calls.CALLS)
                            .where(Calls.CALLS.SID.eq(origin)))) {
                results.add(r.getValue(Calls.CALLS.TID));
            }
            mCallsDownstreamCache.put(origin, results);
            Statistics.CACHE_MISS++;
        } else {
            Statistics.CACHE_HITS++;
        }
        return new Pair<Integer, ArrayList<Integer>>(origin, results);
    }

}

public class CacheDecorator<K, V> {

    public final String TAG = getClass().getSimpleName();

    private CacheAccess<K, V> mCache;

    public CacheDecorator() {
        try {
            mCache = JCS.getInstance("default");
        } catch (CacheException e) {
            BillBoard.e(TAG, "Error getting cache configuration: " + e.toString());
            e.printStackTrace();
        }
    }

    /**
     * Get an object from cache
     * @param obj object to retrieve from cache
     * @return generic object of retrieved value, null if not found
     */
    public V get(K obj) {
        return mCache.get(obj);
    }

    /**
     * Place an object in cache
     * @param key generic key for reference
     * @param obj generic object to be cached
     */
    public synchronized void put(K key, V obj) {
        try {
            if(obj != null) {
                mCache.putSafe(key, obj);
            }
        } catch( CacheException e) {
            //BillBoard.d(TAG, obj.toString());
            //BillBoard.e(TAG, "Error placing item in cache: " + e.toString());
            //e.printStackTrace();
        }
    }

    /**
     * Get the stats from our cache manager
     * @return String of our cache object
     */
    public String getStats() {
        shutDownCache();
        return mCache.getStats();
    }

    public static void shutDownCache() {
        CompositeCacheManager.getInstance().shutDown();
    }
}

可能会或可能不会有所帮助的其他一些细节:

  • Pair<V, K>数据结构只是一个不可变的2对元组类
  • 如果缓存中不存在该对象,则
  • CacheDecorator.get(V obj)会返回null
  • 我在铸造等方面做了很多尝试
  • JClass确实在代码中的其他地方有引用,但在有问题的方法中没有引用
  • JClass是java类的表示,它是一个自定义结构

1 个答案:

答案 0 :(得分:1)

通过更改您的配置以包含documentation中显示的特定于区域的配置,并将区域传递给您的包装器,应该可以解决问题。

看起来您正在为所有包装器使用相同的缓存区域,因此引用相同的缓存区域。穿过你的包装纸。您可以为所有包装器将mCache = JCS.getInstance("default");更改为mCache = JCS.getInstance("uniqueNameForWrapper");吗?