{"record":{"id":"4b336bcab996fad4","repo":"apache/dubbo","slug":"no-such-constructor-public-localclass-getsimplen","errorCode":null,"errorMessage":"No such constructor \"public <localClass.getSimpleName()>(<interfaceClass.getName()>)\" in local implementation class <localClass.getName()>","messagePattern":"No such constructor \"public <localClass\\.getSimpleName\\(\\)>\\(<interfaceClass\\.getName\\(\\)>\\)\" in local implementation class <localClass\\.getName\\(\\)>","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java","lineNumber":493,"sourceCode":"        if (ConfigUtils.isNotEmpty(className)) {\n            Class<?> localClass = ConfigUtils.isDefault(className)\n                    ? ReflectUtils.forName(interfaceClass.getName() + label)\n                    : ReflectUtils.forName(className);\n            verify(interfaceClass, localClass);\n        }\n    }\n\n    private void verify(Class<?> interfaceClass, Class<?> localClass) {\n        if (!interfaceClass.isAssignableFrom(localClass)) {\n            throw new IllegalStateException(\"The local implementation class \" + localClass.getName()\n                    + \" not implement interface \" + interfaceClass.getName());\n        }\n\n        try {\n            // Check if the localClass a constructor with parameter whose type is interfaceClass\n            ReflectUtils.findConstructor(localClass, interfaceClass);\n        } catch (NoSuchMethodException e) {\n            throw new IllegalStateException(\"No such constructor \\\"public \" + localClass.getSimpleName() + \"(\"\n                    + interfaceClass.getName() + \")\\\" in local implementation class \" + localClass.getName());\n        }\n    }\n\n    private void convertRegistryIdsToRegistries() {\n        computeValidRegistryIds();\n        if (StringUtils.isEmpty(registryIds)) {\n            if (CollectionUtils.isEmpty(registries)) {\n                List<RegistryConfig> registryConfigs = getConfigManager().getDefaultRegistries();\n                registryConfigs = new ArrayList<>(registryConfigs);\n                setRegistries(registryConfigs);\n            }\n        } else {\n            String[] ids = COMMA_SPLIT_PATTERN.split(registryIds);\n            List<RegistryConfig> tmpRegistries = new ArrayList<>();\n            Arrays.stream(ids).forEach(id -> {\n                if (tmpRegistries.stream().noneMatch(reg -> reg.getId().equals(id))) {\n                    Optional<RegistryConfig> globalRegistry = getConfigManager().getRegistry(id);","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java#L475-L511","documentation":"Thrown by AbstractInterfaceConfig.verify() when a local implementation class (set via the local/stub attribute) does not expose a public constructor that takes the service interface as its sole parameter. Dubbo's local stub mechanism requires this constructor so the framework can instantiate the stub and inject a reference to the remote interface for client-side logic execution. The verify() method first confirms the local class implements the interface, then uses ReflectUtils.findConstructor() to locate the required constructor signature, throwing IllegalStateException if it cannot.","triggerScenarios":"Calling ServiceConfig.setLocal() or configuring <dubbo:service local=\"...\"> / stub=\"...\" with a class that lacks a `public LocalClass(InterfaceType)` constructor. Also triggered by the local stub SPI when the stub class only has a default no-arg constructor or a constructor with mismatched parameter types.","commonSituations":"Writing a custom local stub for client-side caching/validation logic but forgetting to add the constructor Dubbo mandates. Copying a stub class from another interface without updating the constructor parameter type. Using an older stub pattern (no-arg init) incompatible with Dubbo's required signature.","solutions":["Add a public constructor to the local implementation class whose single parameter is the service interface type, e.g. `public MyLocalImpl(MyService service) { ... }`.","Verify the local class actually implements the declared interface (the preceding isAssignableFrom check must also pass).","Ensure the constructor is public and not generic/erased in a way that prevents reflective lookup."],"exampleFix":"// before\npublic class MyLocalImpl implements MyService {\n    public MyLocalImpl() { }\n}\n// after\npublic class MyLocalImpl implements MyService {\n    private final MyService remote;\n    public MyLocalImpl(MyService remote) { this.remote = remote; }\n}","handlingStrategy":"validation","validationCode":"// Before setting local/stub, verify the constructor exists\nimport org.apache.dubbo.common.utils.ReflectUtils;\n\nClass<?> iface = MyService.class;\nClass<?> local = MyLocalImpl.class;\nif (!iface.isAssignableFrom(local)) {\n    throw new IllegalStateException(\"local class does not implement interface\");\n}\ntry {\n    ReflectUtils.findConstructor(local, iface);\n} catch (NoSuchMethodException e) {\n    throw new IllegalStateException(\"Missing public constructor \" + local.getSimpleName() + \"(\" + iface.getName() + \")\", e);\n}\nserviceConfig.setLocal(local.getName());","typeGuard":"static boolean hasDubboStubConstructor(Class<?> iface, Class<?> local) {\n    if (!iface.isAssignableFrom(local)) return false;\n    try {\n        org.apache.dubbo.common.utils.ReflectUtils.findConstructor(local, iface);\n        return true;\n    } catch (NoSuchMethodException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    serviceConfig.setLocal(MyLocalImpl.class.getName());\n    serviceConfig.export();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"No such constructor\")) {\n        // add the required public Constructor(iface) to the stub class\n    } else throw e;\n}","preventionTips":["Always add a public constructor taking the service interface to any local/stub class.","Run a unit test that reflectively checks the stub constructor before wiring.","Keep stub classes small and dedicated to one interface."],"tags":["config","local-stub","reflection","constructor"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}