{"record":{"id":"4b6b4a9b9c32ecb9","repo":"SonarSource/sonarqube","slug":"modules-should-be-added-as-instances","errorCode":null,"errorMessage":"Modules should be added as instances","messagePattern":"Modules should be added as instances","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sonar-core/src/main/java/org/sonar/core/platform/SpringComponentContainer.java","lineNumber":102,"sourceCode":"    add(new StartableBeanPostProcessor());\n    add(externalExtensions);\n    add(propertyDefs);\n  }\n\n  /**\n   * Beans need to have a unique name, otherwise they'll override each other.\n   * The strategy is:\n   * - For classes, use the classloader + fully qualified class name as the name of the bean\n   * - For instances, use the Classloader + FQCN + toString()\n   * - If the object is a collection, iterate through the elements and apply the same strategy for each of them\n   */\n  @Override\n  public Container add(Object... objects) {\n    for (Object o : objects) {\n      if (o instanceof Class) {\n        Class<?> clazz = (Class<?>) o;\n        if (Module.class.isAssignableFrom(clazz)) {\n          throw new IllegalStateException(\"Modules should be added as instances\");\n        }\n        context.registerBean(componentKeys.ofClass(clazz), clazz);\n        declareExtension(\"\", o);\n      } else if (o instanceof Module module) {\n        module.configure(this);\n      } else if (o instanceof Iterable) {\n        add(Iterables.toArray((Iterable<?>) o, Object.class));\n      } else {\n        registerInstance(o);\n        declareExtension(\"\", o);\n      }\n    }\n    return this;\n  }\n\n  @Override\n  public void addWebApiV2ConfigurationClass(Class<?> clazz) {\n    webConfigurationClasses.add(clazz);","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-core/src/main/java/org/sonar/core/platform/SpringComponentContainer.java#L84-L120","documentation":"SpringComponentContainer.add() throws this IllegalStateException when a Module is passed as a Class instead of an instance. Modules must be configured (module.configure(this) is invoked on instances); registering a Module class as a bean type would skip configuration and silently register it as a component instead, so the container rejects the pattern outright.","triggerScenarios":"Calling container.add(SomeModule.class) where SomeModule implements Module (directly or via subclass) — the Class branch detects Module.class.isAssignableFrom(clazz) and throws.","commonSituations":"Copy-pasting a component registration line and accidentally passing a Module subclass's class literal instead of 'new SomeModule()'; switching from add(new X()) to add(X.class) for a Module.","solutions":["Pass a Module instance instead of the class: container.add(new MyModule()).","Only pass Class objects for components that are not Modules (beans to be instantiated by the container).","If the class genuinely should not be a Module, remove the 'implements Module' declaration."],"exampleFix":"// before\ncontainer.add(CoreModule.class);\n// after\ncontainer.add(new CoreModule());","handlingStrategy":"type-guard","validationCode":"void safeAdd(SpringComponentContainer container, Object... objects) {\n  for (Object o : objects) {\n    if (o instanceof Class<?> clazz && Module.class.isAssignableFrom(clazz)) {\n      throw new IllegalArgumentException(\"Pass Module instances, not classes: \" + clazz.getName());\n    }\n  }\n  container.add(objects);\n}","typeGuard":"boolean isModuleClass(Object o) {\n  return o instanceof Class<?> clazz && Module.class.isAssignableFrom(clazz); // never pass these to add()\n}","tryCatchPattern":"try {\n  container.add(x);\n} catch (IllegalStateException e) {\n  // 'Modules should be added as instances': replace x with new X()\n}","preventionTips":["Always instantiate Modules with new: container.add(new MyModule()).","Reserve Class arguments for bean components only.","Review add() call sites when introducing new Module subclasses."],"tags":["spring","dependency-injection","api-misuse"],"backgroundTag":"invalid-argument-value","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"}