YunaiV/ruoyi-vue-pro · critical · FlowableException

couldn't lookup datasource from {}: {}

Error message

couldn't lookup datasource from {}: {}

What it means

Flowable's AbstractEngineConfiguration.initDataSource() tries a JNDI lookup (new InitialContext().lookup(dataSourceJndiName)) when dataSource is null but dataSourceJndiName is set. If the JNDI name is unbound or the naming provider is unreachable, the lookup throws and Flowable wraps it as a FlowableException with the JNDI name and root cause 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 0418084e22)

Solutions

  1. Confirm the JNDI name exactly matches what is registered in the container (use java:comp/env/ prefix where required).
  2. Register the datasource resource in the app server (Tomcat context.xml, JBoss -ds.xml, etc.).
  3. If running outside a container, set jdbcUrl/jdbcDriver/jdbcUsername instead of dataSourceJndiName, or inject a DataSource bean directly.
  4. Inspect the caused-by message (NamingException) for 'Name not found' vs 'communication refused' to distinguish missing binding from unreachable provider.

Example fix

// before
cfg.setDataSourceJndiName("jdbc/myDs");
// after
cfg.setDataSourceJndiName("java:comp/env/jdbc/myDs");
// plus context.xml:
// <Resource name="jdbc/myDs" auth="Container" type="javax.sql.DataSource" .../>
Defensive patterns

Strategy: validation

Validate before calling

if (cfg.getDataSourceJndiName() != null) {
    try {
        new InitialContext().lookup(cfg.getDataSourceJndiName());
    } catch (NamingException e) {
        throw new IllegalStateException("JNDI name not bound: " + cfg.getDataSourceJndiName(), e);
    }
}

Type guard

null

Try / catch

try {
    engine = cfg.buildProcessEngine();
} catch (FlowableException e) {
    if (e.getMessage().contains("couldn't lookup datasource")) { /* fall back to JDBC props */ }
    throw e;
}

Prevention

When it happens

Trigger: dataSourceJndiName is configured but the resource is not registered in the app server's JNDI tree; deploying a WAR to Tomcat/JBoss without the declared <Resource>; JNDI name typo (e.g. 'jdbc/myDs' vs 'java:comp/env/jdbc/myDs'); running outside a container that lacks a JNDI provider.

Common situations: Moving from embedded datasource (H2) to JNDI in production but forgetting to add the Resource in context.xml/server.xml; running Flowable in a plain main() without a naming context.

Related errors


AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14). Data as JSON: /api/errors/6f980b10efd0c1bd. Report an issue: GitHub.