YunaiV/yudao-cloud · critical · FlowableException
couldn't lookup datasource from {}: {}
Error message
couldn't lookup datasource from {}: {} What it means
Flowable's AbstractEngineConfiguration.initDataSource() tries InitialContext().lookup(dataSourceJndiName) when no DataSource bean was injected. Any NamingException/ClassCastException/communication failure from the JNDI provider is wrapped in this FlowableException, including the JNDI name in the message.
Source
Thrown at sql/dm/flowable-patch/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java:446
/**
* Define a max length for storing String variable types in the database. Mainly used for the Oracle NVARCHAR2 limit of 2000 characters
*/
protected int maxLengthStringVariableType = -1;
protected void initEngineConfigurations() {
addEngineConfiguration(getEngineCfgKey(), getEngineScopeType(), this);
}
// DataSource
// ///////////////////////////////////////////////////////////////
protected void initDataSource() {
if (dataSource == null) {
if (dataSourceJndiName != null) {
try {
dataSource = (DataSource) new InitialContext().lookup(dataSourceJndiName);
} catch (Exception e) {
throw new FlowableException("couldn't lookup datasource from " + dataSourceJndiName + ": " + e.getMessage(), e);
}
} else if (jdbcUrl != null) {
if ((jdbcDriver == null) || (jdbcUsername == null)) {
throw new FlowableException("DataSource or JDBC properties have to be specified in a process engine configuration");
}
logger.debug("initializing datasource to db: {}", jdbcUrl);
if (logger.isInfoEnabled()) {
logger.info("Configuring Datasource with following properties (omitted password for security)");
logger.info("datasource driver : {}", jdbcDriver);
logger.info("datasource url : {}", jdbcUrl);
logger.info("datasource user name : {}", jdbcUsername);
}
PooledDataSource pooledDataSource = new PooledDataSource(this.getClass().getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword);
View on GitHub (pinned to 477be9dd49)
Solutions
- Verify the exact JNDI name against the server's JNDI tree (e.g. WildFly admin console, Tomcat's ResourceLink + web.xml resource-ref).
- On Spring Boot / standalone, skip JNDI and configure jdbcUrl/jdbcDriver/jdbcUsername directly, or inject a DataSource bean via setDataSource().
- Ensure the lookup target is really a javax.sql.DataSource and the app has permission to read it.
- For embedded Tomcat, register the resource in server.context.xml (or TomcatServletWebServerFactory customization) and the ResourceLink in context.xml.
Example fix
// before
cfg.setDataSourceJndiName("java:comp/env/jdbc/flowable"); // fails in Spring Boot
// after
cfg.setJdbcUrl("jdbc:dm://localhost:5236");
cfg.setJdbcDriver("dm.jdbc.driver.DmDriver");
cfg.setJdbcUsername("SYSDBA");
cfg.setJdbcPassword("***"); Defensive patterns
Strategy: validation
Validate before calling
// Fail fast before engine build with a clear message
if (cfg.getDataSource() == null && cfg.getDataSourceJndiName() != null) {
try {
DataSource ds = (DataSource) new InitialContext().lookup(cfg.getDataSourceJndiName());
Assert.notNull(ds, "JNDI name resolved to null");
} catch (Exception e) {
throw new IllegalStateException("JNDI datasource unavailable: " + cfg.getDataSourceJndiName(), e);
}
} Try / catch
try {
processEngine = cfg.buildProcessEngine();
} catch (FlowableException e) {
if (e.getMessage() != null && e.getMessage().startsWith("couldn't lookup datasource")) {
// fall back to direct JDBC config or fail with actionable guidance
throw new IllegalStateException("Configure a valid JNDI name or set jdbc* properties", e);
}
throw e;
} Prevention
- In Spring Boot / standalone apps, prefer setDataSource() or jdbc* properties over JNDI
- Smoke-test JNDI lookups in a startup health check before the engine builds
When it happens
Trigger: ProcessEngineConfiguration is built with setDataSourceJndiName("java:comp/env/jdbc/ds") but the app runs outside a container with no JNDI tree, or the name is misspelled, or the bound object is not a javax.sql.DataSource (cast fails), or the app server resource is not deployed/started.
Common situations: Moving a Flowable app from a full app server (WildFly/TomEE with JNDI) to Spring Boot embedded Tomcat which has no java:comp/env by default; typos in the JNDI name; resource adapter not yet published during early startup; running unit tests without a JNDI implementation.
Related errors
- DataSource or JDBC properties have to be specified in a proc
- invalid command interceptor chain configuration: {}
- couldn't deduct database type from database product name '{}
- Exception while initializing Database connection
- Error while building ibatis SqlSessionFactory: {}
AI-assisted analysis of YunaiV/yudao-cloud@477be9dd49 (2026-08-14).
Data as JSON: /api/errors/57310b6c6875c3f2.
Report an issue: GitHub.