nathanmarz/storm · error · RuntimeException
Must submit topologies using the 'storm' client script so…
Error message
Must submit topologies using the 'storm' client script so that StormSubmitter knows which jar to upload.
What it means
submitJar requires the localJar path to be non-null; the 'storm' client script sets it so StormSubmitter knows which jar to upload to Nimbus. Running the topology's main class directly (e.g. `java -cp ... Main`) leaves localJar null, so a RuntimeException is thrown.
Solutions
- Submit via the storm client: `storm jar mytopology.jar com.mypack.MyTopology <name>`.
- If you must launch with java, set the jar path yourself and call StormSubmitter.submitJar(conf, localJar) explicitly.
- For IDEs, create a run configuration that mimics the storm script or use local mode (LocalCluster) instead.
- Guard the code: only call submitTopology when running under the storm script.
Example fix
// before
StormSubmitter.submitTopology(name, conf, topology); // run via plain java
// after - guard
if (System.getProperty("storm.jar") == null) {
throw new IllegalStateException("Run with: storm jar app.jar ...");
}
StormSubmitter.submitTopology(name, conf, topology); Defensive patterns
Strategy: validation
Validate before calling
// ensure we're running under 'storm jar' before submitting
if (System.getProperty("storm.jar") == null) {
throw new IllegalStateException("Use: storm jar <jar> <mainClass> ...");
} Try / catch
try {
StormSubmitter.submitTopology(name, conf, topology);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("'storm' client script")) {
log.error("Re-run via: storm jar app.jar " + Main.class.getName());
} else { throw e; }
} Prevention
- Always deploy via the storm CLI wrapper, never plain java for remote submit.
- Use LocalCluster for IDE/debug runs instead of submitTopology.
- Add the storm.jar system-property check at the top of your main method.
When it happens
Trigger: Running the topology main class with plain `java` instead of the `storm jar` wrapper; calling StormSubmitter.submitTopology from a context where the jar path was never injected; running from an IDE without the storm client script.
Common situations: IDE run configurations launching topology main directly; local tests accidentally calling submitTopology; docs examples copied without using the storm CLI.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Each element of the list
- Field must be an Iterable of
- Field must be a power of 2.
- Topology with name ` ` already exists on cluster
- No DRPC servers configured for topology
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/3be1c671284d9e9c.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/backtype/storm/StormSubmitter.java:148
client.close();
}
}
private static String submittedJar = null;
private static void submitJar(Map conf) {
if(submittedJar==null) {
LOG.info("Jar not uploaded to master yet. Submitting jar...");
String localJar = System.getProperty("storm.jar");
submittedJar = submitJar(conf, localJar);
} else {
LOG.info("Jar already uploaded to master. Not submitting jar.");
}
}
public static String submitJar(Map conf, String localJar) {
if(localJar==null) {
throw new RuntimeException("Must submit topologies using the 'storm' client script so that StormSubmitter knows which jar to upload.");
}
NimbusClient client = NimbusClient.getConfiguredClient(conf);
try {
String uploadLocation = client.getClient().beginFileUpload();
LOG.info("Uploading topology jar " + localJar + " to assigned location: " + uploadLocation);
BufferFileInputStream is = new BufferFileInputStream(localJar);
while(true) {
byte[] toSubmit = is.read();
if(toSubmit.length==0) break;
client.getClient().uploadChunk(uploadLocation, ByteBuffer.wrap(toSubmit));
}
client.getClient().finishFileUpload(uploadLocation);
LOG.info("Successfully uploaded topology jar to assigned location: " + uploadLocation);
return uploadLocation;
} catch(Exception e) {
throw new RuntimeException(e);
} finally {
client.close();View on GitHub (pinned to cdb116e942)