{"record":{"id":"3d607751a0d06cb8","repo":"apache/dubbo","slug":"unable-to-determine-bean-class-from-factory-s-supe","errorCode":null,"errorMessage":"unable to determine bean class from factory's superclass or interface","messagePattern":"unable to determine bean class from factory's superclass or interface","errorType":"exception","errorClass":"ScopeBeanException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java","lineNumber":110,"sourceCode":"    }\n\n    public <T> void registerBeanDefinition(Class<T> clazz) {\n        registerBeanDefinition(null, clazz);\n    }\n\n    public <T> void registerBeanDefinition(String name, Class<T> clazz) {\n        registeredBeanDefinitions.add(new BeanDefinition<>(name, clazz));\n    }\n\n    public <T> void registerBeanFactory(Supplier<T> factory) {\n        registerBeanFactory(null, factory);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public <T> void registerBeanFactory(String name, Supplier<T> factory) {\n        Class<T> clazz = (Class<T>) TypeUtils.getSuperGenericType(factory.getClass(), 0);\n        if (clazz == null) {\n            throw new ScopeBeanException(\"unable to determine bean class from factory's superclass or interface\");\n        }\n        registeredBeanDefinitions.add(new BeanDefinition<>(name, clazz, factory));\n    }\n\n    private <T> T createAndRegisterBean(String name, Class<T> clazz) {\n        checkDestroyed();\n        T instance = getBean(name, clazz);\n        if (instance != null) {\n            throw new ScopeBeanException(\n                    \"already exists bean with same name and type, name=\" + name + \", type=\" + clazz.getName());\n        }\n        try {\n            instance = instantiationStrategy.instantiate(clazz);\n        } catch (Throwable e) {\n            throw new ScopeBeanException(\"create bean instance failed, type=\" + clazz.getName(), e);\n        }\n        registerBean(name, instance);\n        return instance;","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java#L92-L128","documentation":"Thrown by ScopeBeanFactory.registerBeanFactory(String, Supplier) when TypeUtils.getSuperGenericType(factory.getClass(), 0) returns null, meaning the bean type produced by the Supplier cannot be inferred from the factory's generic supertype. Dubbo needs the produced type to build a BeanDefinition, so it refuses to register an untyped factory. This happens when the Supplier is a raw type, a method reference/lambda whose target type is erased, or a class whose generic parameter is not reified.","triggerScenarios":"Calling registerBeanFactory(supplier) where supplier is a plain java.util.function.Supplier, a lambda like () -> new MyBean() assigned to a raw Supplier variable, or a Supplier<T> subclass whose generic argument cannot be resolved at runtime. Also when the factory class implements Supplier with a non-generic or raw supertype.","commonSituations":"Registering a bean factory via reflection or a DI bridge where generics are erased; migrating code that previously used registerBean(Class) and switching to a Supplier without preserving the generic type; using method references assigned to raw Supplier fields.","solutions":["Register the bean by class instead: registerBeanDefinition(name, MyBean.class) or registerBean(name, MyBean.class).","Provide the type explicitly by using the overload that lets Dubbo infer it: subclass Supplier with a reified generic, e.g. anonymous new Supplier<MyBean>() { ... } instead of a raw/lambda Supplier.","If you must use a factory, register the already-constructed instance with registerBean(name, instance).","Ensure the factory object's class implements Supplier<ConcreteType> (not raw Supplier) so TypeUtils can read the parameter type."],"exampleFix":"// before\nSupplier raw = () -> new MyBean();\nscopeBeanFactory.registerBeanFactory(\"myBean\", raw);  // type erased\n// after\nscopeBeanFactory.registerBeanDefinition(\"myBean\", MyBean.class);\n// or\nSupplier<MyBean> typed = () -> new MyBean();\nscopeBeanFactory.registerBeanFactory(\"myBean\", typed);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Ensure the factory exposes a reified bean type before registering\n<T> boolean factoryTypeIsResolvable(Supplier<T> factory) {\n    return org.apache.dubbo.common.utils.TypeUtils.getSuperGenericType(\n               factory.getClass(), 0) != null;\n}","tryCatchPattern":"try {\n    factory.registerBeanFactory(name, supplier);\n} catch (ScopeBeanException e) {\n    if (e.getMessage().contains(\"unable to determine bean class\")) {\n        // fall back to registering the bean by class or by instance\n        factory.registerBeanDefinition(name, MyBean.class);\n    } else throw e;\n}","preventionTips":["Prefer registerBean(name, Class) or registerBeanDefinition when the type is known statically.","Use anonymous new Supplier<ConcreteType>() { ... } instead of raw Supplier/lambda assigned to a raw variable.","Avoid reflective wiring that erases the generic parameter of a Supplier.","If construction needs custom logic, register an explicit BeanDefinition with both class and factory."],"tags":["bean-factory","generics","reflection","dubbo-common"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}