{"record":{"id":"077bb3620939528d","repo":"apache/dubbo","slug":"non-public-interfaces-from-different-packages","errorCode":null,"errorMessage":"non-public interfaces from different packages","messagePattern":"non-public interfaces from different packages","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java","lineNumber":133,"sourceCode":"        return sb.toString();\n    }\n\n    private static Class<?> buildProxyClass(ClassLoader cl, Class<?>[] ics, ProtectionDomain domain) {\n        ClassGenerator ccp = null;\n        try {\n            ccp = ClassGenerator.newInstance(cl);\n\n            Set<String> worked = new HashSet<>();\n            List<Method> methods = new ArrayList<>();\n\n            String pkg = ics[0].getPackage().getName();\n            Class<?> neighbor = ics[0];\n\n            for (Class<?> ic : ics) {\n                String npkg = ic.getPackage().getName();\n                if (!Modifier.isPublic(ic.getModifiers())) {\n                    if (!pkg.equals(npkg)) {\n                        throw new IllegalArgumentException(\"non-public interfaces from different packages\");\n                    }\n                }\n\n                ccp.addInterface(ic);\n\n                for (Method method : ic.getMethods()) {\n                    String desc = ReflectUtils.getDesc(method);\n                    if (worked.contains(desc) || Modifier.isStatic(method.getModifiers())) {\n                        continue;\n                    }\n                    worked.add(desc);\n\n                    int ix = methods.size();\n                    Class<?> rt = method.getReturnType();\n                    Class<?>[] pts = method.getParameterTypes();\n\n                    StringBuilder code = new StringBuilder(\"Object[] args = new Object[\")\n                            .append(pts.length)","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java#L115-L151","documentation":"Thrown by Proxy.buildProxyClass when one or more interfaces are non-public and their package differs from that of ics[0]. The generated proxy class is placed in the package of the first interface so it can access package-private interfaces; a non-public interface from a different package cannot be implemented from there, so Dubbo aborts with IllegalArgumentException.","triggerScenarios":"Proxy.getProxy(ics) where ics mixes package-private interfaces from package X with a first interface (or other non-public interface) from package Y.","commonSituations":"Internal SPI interfaces that are not public and originate from different modules/packages; combining a public API interface with a package-private extension interface from another package.","solutions":["Make all interfaces passed to getProxy public.","If some must stay package-private, keep them all in the same package as ics[0].","Order the array so ics[0] is in the same package as every other non-public interface (only helps if all non-public share one package)."],"exampleFix":"// before\npackage a.b; interface InternalA {} // package-private\npackage c.d; public interface PublicB {}\nProxy.getProxy(InternalA.class, PublicB.class);\n\n// after\npackage a.b; public interface InternalA {} // promote to public","handlingStrategy":"validation","validationCode":"String pkg0 = ics[0].getPackageName();\nfor (Class<?> ic : ics) {\n    if (!Modifier.isPublic(ic.getModifiers()) && !ic.getPackageName().equals(pkg0)) {\n        throw new IllegalArgumentException(\"non-public interface \" + ic + \" from a different package\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make all proxied interfaces public.","Keep any package-private interfaces in the same package as ics[0].","Validate interface visibility and packages before calling getProxy."],"tags":["bytecode","proxy","visibility","validation"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}