{"record":{"id":"dd689e82c0c13bd2","repo":"redis/jedis","slug":"failed-to-insantiate-custom-cache-type","errorCode":null,"errorMessage":"Failed to insantiate custom cache type!","messagePattern":"Failed to insantiate custom cache type!","errorType":"exception","errorClass":"JedisCacheException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/csc/CacheFactory.java","lineNumber":33,"sourceCode":"            }\n            return new DefaultCache(config.getMaxSize(), config.getCacheable(), getEvictionPolicy(config));\n        }\n        return instantiateCustomCache(config);\n    }\n\n    private static Cache instantiateCustomCache(CacheConfig config) {\n        try {\n            if (config.getCacheable() != null) {\n                Constructor ctorWithCacheable = findConstructorWithCacheable(config.getCacheClass());\n                if (ctorWithCacheable != null) {\n                    return (Cache) ctorWithCacheable.newInstance(config.getMaxSize(), getEvictionPolicy(config), config.getCacheable());\n                }\n            }\n            Constructor ctor = getConstructor(config.getCacheClass());\n            return (Cache) ctor.newInstance(config.getMaxSize(), getEvictionPolicy(config));\n        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException\n                | SecurityException e) {\n            throw new JedisCacheException(\"Failed to insantiate custom cache type!\", e);\n        }\n    }\n\n    private static Constructor findConstructorWithCacheable(Class customCacheType) {\n        return Arrays.stream(customCacheType.getConstructors())\n                .filter(ctor -> Arrays.equals(ctor.getParameterTypes(), new Class[] { int.class, EvictionPolicy.class, Cacheable.class }))\n                .findFirst().orElse(null);\n    }\n\n    private static Constructor getConstructor(Class customCacheType) {\n        try {\n            return customCacheType.getConstructor(int.class, EvictionPolicy.class);\n        } catch (NoSuchMethodException e) {\n            String className = customCacheType.getName();\n            throw new JedisCacheException(String.format(\n                \"Failed to find compatible constructor for custom cache type!  Provide one of these;\"\n                        // give hints about the compatible constructors\n                        + \"\\n - %s(int maxSize, EvictionPolicy evictionPolicy)\\n - %s(int maxSize, EvictionPolicy evictionPolicy, Cacheable cacheable)\",","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/csc/CacheFactory.java#L15-L51","documentation":"instantiateCustomCache reflectively constructs the configured custom Cache class via a (int maxSize, EvictionPolicy) constructor; any reflective failure — InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException (the constructor itself threw), or SecurityException — is wrapped in JedisCacheException('Failed to insantiate custom cache type!'). Check the wrapped cause for the real reason.","triggerScenarios":"config.setCacheClass(X.class) where X is abstract or an interface (InstantiationException); the (int, EvictionPolicy) constructor throws internally (InvocationTargetException); the constructor rejects the maxSize/eviction arguments (IllegalArgumentException); a SecurityManager blocks reflection; the class's constructor is not accessible.","commonSituations":"Custom cache implementations with constructor-side validation that throws on the given maxSize (e.g. maxSize <= 0); pointing cacheClass at a Cache interface or abstract base class; container/environments with strict security policies limiting reflection.","solutions":["Inspect e.getCause() in the message/stacktrace to find the constructor's own exception and fix it.","Ensure the custom cache class is concrete, public, and has a public (int maxSize, EvictionPolicy evictionPolicy) constructor (or the 3-arg variant with Cacheable).","Validate maxSize and eviction policy values before building CacheConfig (e.g. maxSize > 0).","Check the constructor body for throw statements that could fire for your config values."],"exampleFix":"// before\nclass MyCache extends AbstractCache {\n  private MyCache(int maxSize, EvictionPolicy policy) { ... } // non-public -> IllegalAccessException\n}\n// after\nclass MyCache extends AbstractCache {\n  public MyCache(int maxSize, EvictionPolicy policy) {\n    if (maxSize <= 0) throw new IllegalArgumentException(\"maxSize must be > 0\");\n    ...\n  }\n}","handlingStrategy":"try-catch","validationCode":"Class<? extends Cache> type = config.getCacheClass();\nif (type != null) {\n  if (Modifier.isAbstract(type.getModifiers()) || type.isInterface())\n    throw new IllegalArgumentException(type + \" must be a concrete class\");\n  boolean hasCtor = Arrays.stream(type.getConstructors())\n      .anyMatch(c -> Arrays.equals(c.getParameterTypes(), new Class[]{int.class, EvictionPolicy.class}));\n  if (!hasCtor) throw new IllegalArgumentException(type + \" lacks public (int, EvictionPolicy) constructor\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  Cache cache = CacheFactory.getCache(config);\n} catch (JedisCacheException e) {\n  if (e.getMessage().contains(\"insantiate custom cache\")) {\n    Throwable cause = e.getCause(); // InstantiationException/InvocationTargetException etc.\n    log.error(\"custom cache construction failed\", cause);\n  } else throw e;\n}","preventionTips":["Keep the (int, EvictionPolicy) constructor public, concrete, and side-effect free","Validate maxSize/eviction arguments in the constructor and keep the cause message descriptive","Unit-test CacheFactory.getCache(config) for your custom cache class"],"tags":["reflection","cache","instantiation-failed"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}