{"record":{"id":"df50e1d03f253449","repo":"jeecgboot/JeecgBoot","slug":"ruleclass-ifillrulehandler","errorCode":null,"errorMessage":"类 {ruleClass} 未实现 IFillRuleHandler 接口","messagePattern":"类 (.+?) 未实现 IFillRuleHandler 接口","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/FillRuleUtil.java","lineNumber":87,"sourceCode":"                        params.put(key, value);\n                    }\n                }\n\n                if (formData == null) {\n                    formData = new JSONObject();\n                }\n                // 包路径白名单校验，防止任意类加载漏洞\n                if (!ruleClass.startsWith(\"org.jeecg.\")) {\n                    log.error(\"检测到非法填值规则类加载尝试: {}\", ruleClass);\n                    throw new SecurityException(\"不允许加载非 org.jeecg 包路径下的填值规则类: \" + ruleClass);\n                }\n\n                // 通过反射执行配置的类里的方法（先加载类并校验接口，再实例化）\n                //update-begin---author:scott ---date:20260416  for：【PR#9538】Class.forName使用上下文类加载器，增强部署兼容性-----------\n                Class<?> clazz = Class.forName(ruleClass, true, Thread.currentThread().getContextClassLoader());\n                //update-end---author:scott ---date:20260416  for：【PR#9538】Class.forName使用上下文类加载器，增强部署兼容性-----------\n                if (!IFillRuleHandler.class.isAssignableFrom(clazz)) {\n                    throw new IllegalArgumentException(\"类 \" + ruleClass + \" 未实现 IFillRuleHandler 接口\");\n                }\n                IFillRuleHandler ruleHandler = (IFillRuleHandler) clazz.getDeclaredConstructor().newInstance();\n                return ruleHandler.execute(params, formData);\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n        return null;\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":98,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/FillRuleUtil.java#L69-L98","documentation":"Thrown by FillRuleUtil.executeRule after successfully loading ruleClass via reflection when the loaded class does not implement org.jeecg.common.handler.IFillRuleHandler. The isAssignableFrom check fails and an IllegalArgumentException is thrown. Note: because the surrounding try-catch swallows all exceptions (e.printStackTrace then returns null), the exception does not propagate — the method silently returns null.","triggerScenarios":"A sys_fill_rule row points rule_class to a valid org.jeecg.* class that exists on the classpath but does not implement IFillRuleHandler; or the class was refactored/renamed and no longer implements the interface.","commonSituations":"Class name copy-pasted incorrectly into rule_class; the handler class was an early prototype that never implemented the interface; a version upgrade changed the interface or moved it; the configured class is a plain POJO rather than a rule handler.","solutions":["Make the configured class implement org.jeecg.common.handler.IFillRuleHandler and override execute(JSONObject params, JSONObject formData).","Verify the fully-qualified class name in sys_fill_rule.rule_class matches the actual class and package.","Ensure the class has a public no-arg constructor (getDeclaredConstructor().newInstance() is used).","Because the outer catch swallows this, check application logs for the printed stack trace when executeRule unexpectedly returns null."],"exampleFix":"// before\npackage org.jeecg.modules.demo;\npublic class MyRule { // does not implement IFillRuleHandler\n    public Object execute() { return \"x\"; }\n}\n\n// after\npackage org.jeecg.modules.demo;\nimport org.jeecg.common.handler.IFillRuleHandler;\npublic class MyRule implements IFillRuleHandler {\n    public MyRule() {}\n    @Override\n    public Object execute(JSONObject params, JSONObject formData) { return \"x\"; }\n}","handlingStrategy":"try-catch","validationCode":"Class<?> clazz = Class.forName(ruleClass);\nif (!IFillRuleHandler.class.isAssignableFrom(clazz)) {\n    throw new IllegalArgumentException(ruleClass + \" 未实现 IFillRuleHandler\");\n}","typeGuard":"null","tryCatchPattern":"// Note: FillRuleUtil.executeRule swallows all exceptions and returns null.\n// Check logs for the printed stack trace when the result is unexpectedly null.\nObject result = FillRuleUtil.executeRule(ruleCode, formData);\nif (result == null) {\n    log.warn(\"填值规则 [{}] 执行失败或未配置，请检查 rule_class 与接口实现\", ruleCode);\n}","preventionTips":["Ensure configured classes implement IFillRuleHandler and have a no-arg constructor.","Because executeRule swallows exceptions, rely on logs to diagnose null returns.","Validate rule_class against the classpath during configuration."],"tags":["reflection","fill-rule","configuration","interface"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}