{"record":{"id":"fb2e7f962e92cd0c","repo":"nathanmarz/storm","slug":"could-not-instantiate-a-class-listed-in-config-under-section","errorCode":null,"errorMessage":"Could not instantiate a class listed in config under section ${Config.TOPOLOGY_METRICS_CONSUMER_REGISTER} with fully qualified name ${_consumerClassName}","messagePattern":"Could not instantiate a class listed in config under section (.+?) with fully qualified name (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"storm-core/src/jvm/backtype/storm/metric/MetricsConsumerBolt.java","lineNumber":46,"sourceCode":"import java.util.Map;\n\npublic class MetricsConsumerBolt implements IBolt {\n    IMetricsConsumer _metricsConsumer;\n    String _consumerClassName;\n    OutputCollector _collector;\n    Object _registrationArgument;\n\n    public MetricsConsumerBolt(String consumerClassName, Object registrationArgument) {\n        _consumerClassName = consumerClassName;\n        _registrationArgument = registrationArgument;\n    }\n\n    @Override\n    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {\n        try {\n            _metricsConsumer = (IMetricsConsumer)Class.forName(_consumerClassName).newInstance();\n        } catch (Exception e) {\n            throw new RuntimeException(\"Could not instantiate a class listed in config under section \" +\n                Config.TOPOLOGY_METRICS_CONSUMER_REGISTER + \" with fully qualified name \" + _consumerClassName, e);\n        }\n        _metricsConsumer.prepare(stormConf, _registrationArgument, context, (IErrorReporter)collector);\n        _collector = collector;\n    }\n    \n    @Override\n    public void execute(Tuple input) {\n        _metricsConsumer.handleDataPoints((IMetricsConsumer.TaskInfo)input.getValue(0), (Collection)input.getValue(1));\n        _collector.ack(input);\n    }\n\n    @Override\n    public void cleanup() {\n        _metricsConsumer.cleanup();\n    }\n    \n}","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/backtype/storm/metric/MetricsConsumerBolt.java#L28-L64","documentation":"During MetricsConsumerBolt.prepare, Storm reflectively instantiates each class registered under Config.TOPOLOGY_METRICS_CONSUMER_REGISTER via Class.forName(...).newInstance() and casts it to IMetricsConsumer. This RuntimeException wraps any failure in that process: the class name is wrong, the class is not on the worker's classpath, it lacks a no-arg constructor, is abstract/an interface, or its constructor/initialization throws. Because it fires in bolt prepare, the topology's system-metrics bolt fails to start.","triggerScenarios":"Class.forName fails (typo in 'class' field, class not in topology jar/worker classpath), newInstance fails (no public no-arg constructor, abstract class, constructor throws), or the instantiated object is not castable to IMetricsConsumer.","commonSituations":"Typo or wrong fully-qualified name in topology.metrics.consumer.register; custom IMetricsConsumer implementation missing from the submitted jar; class was refactored/renamed across Storm versions (e.g. backtype.storm vs org.apache.storm packages) leaving stale config; implementing class has only a constructor with arguments.","solutions":["Verify the 'class' entry in Config.TOPOLOGY_METRICS_CONSUMER_REGISTER is the exact fully-qualified class name (correct package, correct case).","Ensure the class (and its dependencies) are bundled in the topology jar on the worker classpath.","Give the consumer a public no-arg constructor and make it concrete (non-abstract) and implement backtype.storm.metric.IMetricsConsumer.","Instantiate the class manually in a test (new MyConsumer()) to surface the wrapped cause 'e' in the stack trace and fix that root issue."],"exampleFix":"// before\ntopology.metrics.consumer.register:\n  - class: \"com.example.MetricConsumer\"   // typo, class is com.example.MetricsConsumer\n// after\ntopology.metrics.consumer.register:\n  - class: \"com.example.MetricsConsumer\"","handlingStrategy":"validation","validationCode":"String cls = (String) consumerConf.get(\"class\");\ntry {\n    Class<?> c = Class.forName(cls);\n    if (!backtype.storm.metric.IMetricsConsumer.class.isAssignableFrom(c))\n        throw new IllegalArgumentException(cls + \" does not implement IMetricsConsumer\");\n    c.getDeclaredConstructor().setAccessible(true); // fails here if no no-arg ctor\n    c.newInstance();\n} catch (Exception e) {\n    throw new IllegalStateException(\"metrics consumer class not loadable/instantiable: \" + cls, e);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep metrics consumer classes in the same jar you submit with the topology (or on the worker classpath).","Test Class.forName + newInstance of every configured consumer in a unit test before deploying.","Always implement IMetricsConsumer with a public no-arg constructor.","After package renames (backtype.storm -> org.apache.storm), re-verify config class names."],"tags":["reflection","config","metrics","classpath","storm"],"backgroundTag":"class-not-found","analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}