flowable/flowable-engine · error · FlowableException
resource '${resource}' not found
Error message
resource '${resource}' not found What it means
FlowableException thrown by CmmnDeploymentBuilderImpl.addClasspathResource when the class loader cannot locate the given resource on the classpath. getResourceAsStream returns null for a missing resource, and the builder converts that into an explicit error before building the CMMN deployment. It means the deployment resource path/name does not match any classpath entry.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/repository/CmmnDeploymentBuilderImpl.java:77
throw new FlowableException("could not get byte array from resource '" + resourceName + "'", e);
}
if (bytes == null) {
throw new FlowableException("byte array for resource '" + resourceName + "' is null");
}
CmmnResourceEntity resource = resourceEntityManager.create();
resource.setName(resourceName);
resource.setBytes(bytes);
deployment.addResource(resource);
return this;
}
@Override
public CmmnDeploymentBuilder addClasspathResource(String resource) {
try (final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(resource)) {
if (inputStream == null) {
throw new FlowableException("resource '" + resource + "' not found");
}
return addInputStream(resource, inputStream);
} catch (IOException ex) {
throw new FlowableException("Failed to read resource " + resource, ex);
}
}
@Override
public CmmnDeploymentBuilder addString(String resourceName, String text) {
if (text == null) {
throw new FlowableException("text is null");
}
CmmnResourceEntity resource = resourceEntityManager.create();
resource.setName(resourceName);
resource.setBytes(text.getBytes(StandardCharsets.UTF_8));
deployment.addResource(resource);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Verify the resource exists exactly at the given path under src/main/resources and fix the path string
- Check the file was compiled/packaged into target/classes (or the jar); run a clean build
- Try ClassLoader lookup in isolation to confirm resolution before calling addClasspathResource
- If loading from the filesystem instead, use addInputStream(new FileInputStream(...)) rather than a classpath path
Example fix
// before
repositoryService.createDeployment().addClasspathResource("diagrams/order-process.xml");
// after
repositoryService.createDeployment().addClasspathResource("processes/order-process.cmmn.xml"); // path matches src/main/resources/processes/order-process.cmmn.xml Defensive patterns
Strategy: validation
Validate before calling
boolean exists = Thread.currentThread().getContextClassLoader().getResource(resource) != null || CmmnDeploymentBuilderImpl.class.getClassLoader().getResource(resource) != null;
if (!exists) throw new IllegalArgumentException("Classpath resource missing: " + resource); Type guard
static boolean classpathResourceExists(String resource) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return resource != null && (cl.getResource(resource) != null || CmmnDeploymentBuilderImpl.class.getClassLoader().getResource(resource) != null);
} Try / catch
try {
builder.addClasspathResource(resource);
} catch (FlowableException e) {
if (e.getMessage() != null && e.getMessage().contains("not found")) {
throw new ConfigurationException("CMMN resource not on classpath: " + resource, e);
}
throw e;
} Prevention
- Keep a single constant/enum of resource paths used in deployments
- Add a startup test that deploys all declared resources to catch path drift
- Verify resources land in target/classes after build (mvn clean package; jar tf)
- Avoid mixing leading-slash and package-relative resource conventions
When it happens
Trigger: Calling cmmnRepositoryService.createDeployment().addClasspathResource("some/path.xml") where the path does not exist under src/main/resources (or test resources), the file name is misspelled, or the resource is not packaged into the jar/war.
Common situations: Wrong relative path (leading slash confusion, wrong package directory), resource excluded by Maven/Gradle resource filtering or packaging config, deploying from a shaded/fat jar where resources were not included, renaming the .cmmn/.cmmn10/.xml file without updating code.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- resource '${resource}' not found
- No event model found for event key ${key} for ${planItemInst
- inputStream for resource '${resourceName}' is null
- resource '${resource}' doesn't exist
- resource '${resource}' not found
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/6b49bb356b70d2f7.
Report an issue: GitHub.