{"record":{"id":"1324a946aecd59b1","repo":"baomidou/mybatis-plus","slug":"failed-to-extract-groovy-lambda-meta-from-proxy-ha","errorCode":null,"errorMessage":"Failed to extract Groovy lambda meta from proxy handler: {}","messagePattern":"Failed to extract Groovy lambda meta from proxy handler: (.+?)","errorType":"exception","errorClass":"MybatisPlusException","httpStatus":null,"severity":"error","filePath":"mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/support/GroovyLambdaMeta.java","lineNumber":54,"sourceCode":"    private final Class<?> clazz;\n    private final String name;\n\n    public GroovyLambdaMeta(Proxy func) {\n        InvocationHandler handler = Proxy.getInvocationHandler(func);\n        try {\n            Method getDelegate = handler.getClass().getMethod(\"getDelegate\");\n            Object delegate = getDelegate.invoke(handler);\n            Method getMethod = delegate.getClass().getMethod(\"getMethod\");\n            this.name = (String) getMethod.invoke(delegate);\n            Method getOwner = delegate.getClass().getMethod(\"getOwner\");\n            Object owner = getOwner.invoke(delegate);\n            this.clazz = (owner instanceof Class) ? (Class<?>) owner : owner.getClass();\n        } catch (NoSuchMethodException e) {\n            throw new MybatisPlusException(\"Unsupported proxy type for Groovy lambda extraction: \"\n                + handler.getClass().getName()\n                + \". Expected a Groovy ConvertedClosure handler exposing getDelegate().\", e);\n        } catch (Exception e) {\n            throw new MybatisPlusException(\"Failed to extract Groovy lambda meta from proxy handler: \"\n                + handler.getClass().getName(), e);\n        }\n    }\n\n    @Override\n    public String getImplMethodName() {\n        return name;\n    }\n\n    @Override\n    public Class<?> getInstantiatedClass() {\n        return clazz;\n    }\n\n    @Override\n    public String toString() {\n        return clazz.getSimpleName() + \"::\" + name;\n    }","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/baomidou/mybatis-plus/blob/bf67d907478c724120bf76292da54abf9e73c2b3/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/support/GroovyLambdaMeta.java#L36-L72","documentation":"The generic failure branch of GroovyLambdaMeta: getDelegate()/getMethod()/getOwner() were found, but invoking them (or casting the result) threw — IllegalAccessException, InvocationTargetException, or ClassCastException. The handler has the expected shape but the calls fail (security/visibility) or return unexpected types, wrapped as MybatisPlusException('Failed to extract Groovy lambda meta from proxy handler: <handler class>').","triggerScenarios":"Groovy closure delegate methods exist but are not public/accessible (IllegalAccessException), the delegate's getMethod() invocation fails at runtime (InvocationTargetException from a broken closure), or getMethod() does not return a String (ClassCastException on the (String) cast of the method name).","commonSituations":"Groovy security restrictions or non-public synthetic delegate classes under certain Groovy versions; closures compiled with @CompileStatic or Grape-loaded scripts whose delegate returns nonstandard method metadata; mixed Groovy artifact versions on the classpath (groovy jar mismatch).","solutions":["Check the suppressed cause (ex) — IllegalAccessException points to visibility, InvocationTargetException to a failing delegate, ClassCastException to a wrong method-name type.","Normalize the Groovy version: one consistent groovy artifact across the build, matching what the project's mybatis-plus version tests against.","Avoid closure-based wrappers in the affected Groovy code; use explicit column-name conditions.","Upgrade mybatis-plus to pick up fixes in Groovy lambda metadata extraction."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    LambdaQueryWrapper<T> w = Wrappers.lambdaQuery(Entity.class)\n        .eq(closureAsSFunction(Entity::getName), val);\n} catch (MybatisPlusException e) {\n    Throwable cause = e.getCause(); // IllegalAccessException / InvocationTargetException / CCE\n    wrapper.eq(\"name\", val); // degrade to column-name condition\n}","preventionTips":["Inspect the cause chain to distinguish access, invocation, and cast failures.","Use one consistent Groovy artifact version across the classpath.","Avoid closure-based wrapper APIs in Groovy hot paths; use explicit column names."],"tags":["groovy","lambda","reflection","classpath"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}