{"record":{"id":"cd8bd0ec2a40a0f7","repo":"apache/dubbo","slug":"is-not-visible-from-class-loader","errorCode":null,"errorMessage":"{} is not visible from class loader","messagePattern":"(.+?) is not visible from class loader","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java","lineNumber":110,"sourceCode":"        return proxy;\n    }\n\n    private static String buildInterfacesKey(ClassLoader cl, Class<?>[] ics) {\n        StringBuilder sb = new StringBuilder();\n        for (Class<?> ic : ics) {\n            String itf = ic.getName();\n            if (!ic.isInterface()) {\n                throw new RuntimeException(itf + \" is not a interface.\");\n            }\n\n            Class<?> tmp = null;\n            try {\n                tmp = Class.forName(itf, false, cl);\n            } catch (ClassNotFoundException ignore) {\n            }\n\n            if (tmp != ic) {\n                throw new IllegalArgumentException(ic + \" is not visible from class loader\");\n            }\n\n            sb.append(itf).append(';');\n        }\n        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","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java#L92-L128","documentation":"Thrown by Proxy.buildInterfacesKey when an interface class cannot be re-resolved through the ClassLoader of ics[0] (Class.forName(itf, false, cl) returns a different Class object or null). This is the classic multi-classloader visibility problem: the interface was loaded by one loader but is invisible to the loader that will define the proxy.","triggerScenarios":"Proxy.getProxy(ics) in an OSGi, Tomcat, or nested-loader environment where ics[0]'s ClassLoader cannot see one of the other interfaces; interface loaded by the boot loader while cl is an app loader that resolves a different copy.","commonSituations":"OSGi bundles where the interface is not exported; web app with a shared loader vs webapp loader mismatch; the same interface class present in two jars loaded by different loaders (class identity clash); Spring Boot nested jars where the interface is in a parent loader not visible to the child.","solutions":["Pass interfaces that are all visible from a single shared ClassLoader; for OSGi, ensure the interface package is exported.","Make sure there is only one copy of the interface class on the classpath (no duplicate jars in different loaders).","If using a custom loader, ensure it delegates to the loader that already defined the interface.","Check ics[0].getClassLoader() can Class.forName each other interface."],"exampleFix":"// before\n// interface loaded by bundleA's loader, passed alongside classes from bundleB\nProxy.getProxy(MixedFromBundles.class);\n\n// after\n// export the interface package in OSGi and call from a bundle that sees all of them,\n// or pass a ClassLoader that can resolve every interface:\nProxy.getProxy(MyService.class); // ensure MyService visible from ics[0]'s loader","handlingStrategy":"validation","validationCode":"ClassLoader cl = ics[0].getClassLoader();\nfor (Class<?> ic : ics) {\n    Class<?> resolved = Class.forName(ic.getName(), false, cl);\n    if (resolved != ic) {\n        throw new IllegalStateException(ic + \" not visible from loader \" + cl);\n    }\n}\nProxy.getProxy(ics);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure all interfaces are loaded by the same ClassLoader (or a loader visible to ics[0]'s loader).","In OSGi, export the interface packages.","Remove duplicate copies of interface jars from different loaders."],"tags":["bytecode","proxy","classloader","osgi"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}