{"record":{"id":"3c69930e0a4020ab","repo":"SonarSource/sonarqube","slug":"i18n-classloader-does-support-only-resources-but","errorCode":null,"errorMessage":"I18n classloader does support only resources, but not classes","messagePattern":"I18n classloader does support only resources, but not classes","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sonar-core/src/main/java/org/sonar/core/i18n/I18nClassloader.java","lineNumber":61,"sourceCode":"  I18nClassloader(List<ClassLoader> pluginClassloaders) {\n    super(new URL[0]);\n    this.pluginClassloaders = pluginClassloaders.toArray(new ClassLoader[pluginClassloaders.size()]);\n  }\n\n  @Override\n  public URL getResource(String name) {\n    for (ClassLoader pluginClassloader : pluginClassloaders) {\n      URL url = pluginClassloader.getResource(name);\n      if (url != null) {\n        return url;\n      }\n    }\n    return getClass().getClassLoader().getResource(name);\n  }\n\n  @Override\n  protected synchronized Class loadClass(String s, boolean b) throws ClassNotFoundException {\n    throw new UnsupportedOperationException(\"I18n classloader does support only resources, but not classes\");\n  }\n\n  @Override\n  public String toString() {\n    return \"i18n-classloader\";\n  }\n\n  private static List<ClassLoader> allPluginClassloaders(PluginRepository pluginRepository) {\n    // accepted limitation: some plugins extend base plugins, sharing the same classloader, so\n    // there may be duplicated classloaders in the list.\n    List<ClassLoader> list = Lists.newArrayList();\n    for (PluginInfo info : pluginRepository.getPluginInfos()) {\n      Plugin plugin = pluginRepository.getPluginInstance(info.getKey());\n      list.add(plugin.getClass().getClassLoader());\n    }\n    list.add(I18nClassloader.class.getClassLoader());\n    return list;\n  }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-core/src/main/java/org/sonar/core/i18n/I18nClassloader.java#L43-L79","documentation":"Guard in I18nClassloader.loadClass: this classloader deliberately aggregates only resources (L10n bundles) from plugin classloaders and is never meant to define classes, so any attempt to load a class through it (instead of only getResource) hits this UnsupportedOperationException. It indicates code is using the loader as a full classloader rather than a resource-only view.","triggerScenarios":"Attempting to load a class through this classloader, e.g. passing it to APIs that resolve classes (Class.forName-style usage, serialization frameworks, reflection helpers).","commonSituations":"Handing the i18n classloader to plugin managers or DI containers that expect a full classloader; debugging code that enumerates classes from all classloaders.","solutions":["Do not use I18nClassloader for class loading; use the platform/plugin classloader instead","Only use it via getResource/getResources for i18n bundles","Refactor calling code to fetch resources, not classes"],"exampleFix":"// before\nClass<?> c = i18nClassloader.loadClass(\"org.sonar.Foo\");\n// after\nClass<?> c = platformClassloader.loadClass(\"org.sonar.Foo\");","handlingStrategy":"type-guard","validationCode":"if (classloader instanceof I18nClassloader) {\n  throw new IllegalStateException(\"Use platform classloader for classes\");\n}\nClass<?> c = classloader.loadClass(name);","typeGuard":"boolean supportsClassLoading(ClassLoader cl) {\n  return !(cl instanceof I18nClassloader);\n}","tryCatchPattern":"try {\n  return classloader.loadClass(name);\n} catch (UnsupportedOperationException e) {\n  return platformClassloader.loadClass(name);\n}","preventionTips":["Never pass I18nClassloader to APIs that load classes","Restrict its use to getResource/getResources calls","Document the resource-only contract where the classloader is handed off"],"tags":["classloader","i18n","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}