flowable/flowable-engine · error · FlowableException
Failed to read resource
Error message
Failed to read resource ${resource} What it means
FlowableException thrown by EventDeploymentBuilderImpl.addClasspathResource when reading a classpath resource fails with an IOException (or the resource stream cannot be processed) during deployment resource loading. The builder loads classpath resources as event/channel definition files into the deployment. The causing IOException is attached as the cause.
Solutions
- Verify the classpath resource exists via getClass().getResourceAsStream(resource) before calling addClasspathResource.
- Check that the underlying file/JAR is readable and not corrupted.
- Inspect the wrapped IOException cause for the actual read failure.
- If the resource is missing, note the distinct 'resource not found' FlowableException path and fix the resource path/name.
Example fix
// before
deploymentBuilder.addClasspathResource("events/order.event");
// after
try (InputStream is = getClass().getClassLoader().getResourceAsStream("events/order.event")) {
if (is != null) {
deploymentBuilder.addInputStream("events/order.event", is);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if (getClass().getClassLoader().getResource(resource) == null) { throw new IllegalArgumentException("classpath resource missing: " + resource); } Type guard
boolean exists = getClass().getClassLoader().getResource(resource) != null;
Try / catch
try { builder.addClasspathResource(resource); } catch (FlowableException e) { LOG.error("failed reading deployment resource " + resource, e.getCause()); throw e; } Prevention
- Check resource existence with getResource before deploying
- Keep definition files on the runtime classpath of the deploying app
- Log the wrapped IOException cause to distinguish missing vs unreadable resources
When it happens
Trigger: Calling EventDeploymentBuilder.addClasspathResource(resource) where the resource exists but reading its InputStream throws IOException (e.g. stream already consumed, broken classloader/JAR).
Common situations: Deploying event definitions from a JAR with a corrupted or closed stream; resources inside an executable JAR accessed via FileInputStream-style assumptions; classloader quirks in app servers.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- byte array for resource
- could not get byte array from resource
- could not get byte array from resource
- Failed to read resource
- problem reading zip input stream
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d747536b1a43b562.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/repository/EventDeploymentBuilderImpl.java:84
}
EventResourceEntity resource = resourceEntityManager.create();
resource.setName(resourceName);
resource.setBytes(bytes);
deployment.addResource(resource);
return this;
}
@Override
public EventDeploymentBuilder 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 EventDeploymentBuilder addString(String resourceName, String text) {
if (text == null) {
throw new FlowableException("text is null");
}
EventResourceEntity resource = resourceEntityManager.create();
resource.setName(resourceName);
resource.setBytes(text.getBytes(StandardCharsets.UTF_8));
deployment.addResource(resource);
return this;
}
@Override
public EventDeploymentBuilder addEventDefinitionBytes(String resourceName, byte[] eventDefinitionBytes) {View on GitHub (pinned to d6d39ce1c6)