flowable/flowable-engine · critical · FlowableException

database update java class '${upgradestepClassName}' can't b

Error message

database update java class '${upgradestepClassName}' can't be instantiated: ${e.getMessage()}

What it means

When a schema script contains an 'execute java <class>' line, executeSchemaResource instantiates that class as a DbUpgradeStep via ReflectUtil. If instantiation fails (class missing, no public no-arg constructor, wrong type, static-init exception), it throws FlowableException wrapping the cause message.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/db/AbstractSqlScriptBasedDbSchemaManager.java:294

                } else if (line.startsWith("-- ")) {

                    if ("-- force-commit".equals(line)) {
                        connection.commit();
                        logger.debug("Forcing commit");

                    } else {
                        logger.debug(line.substring(3));

                    }

                } else if (line.startsWith("execute java ")) {
                    String upgradestepClassName = line.substring(13).trim();
                    DbUpgradeStep dbUpgradeStep = null;
                    try {
                        dbUpgradeStep = (DbUpgradeStep) ReflectUtil.instantiate(upgradestepClassName);
                    } catch (FlowableException e) {
                        throw new FlowableException("database update java class '" + upgradestepClassName + "' can't be instantiated: " + e.getMessage(), e);
                    }
                    try {
                        logger.debug("executing upgrade step java class {}", upgradestepClassName);
                        dbUpgradeStep.execute();
                    } catch (Exception e) {
                        throw new FlowableException("error while executing database update java class '" + upgradestepClassName + "': " + e.getMessage(), e);
                    }

                } else if (line.length() > 0) {

                    if ("oracle".equals(databaseType) && line.startsWith("begin")) {
                        inOraclePlsqlBlock = true;
                        sqlStatement = addSqlStatementPiece(sqlStatement, line);

                    } else if ((line.endsWith(";") && !inOraclePlsqlBlock) || (line.startsWith("/") && inOraclePlsqlBlock)) {

                        if (inOraclePlsqlBlock) {
                            inOraclePlsqlBlock = false;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the complete, matching-version flowable-engine jar (including internal db upgrade classes) is on the classpath.
  2. Read the chained cause (ClassNotFoundException / ClassCastException / InstantiationException) and fix the specific classpath issue.
  3. Avoid shading/relocating Flowable packages if you rely on its schema upgrade scripts.
  4. Perform the upgrade step manually by running the SQL and updating the schema version property if the java step cannot run.

Example fix

// before: shaded jar relocations exclude upgrade steps
<relocations><relocation><pattern>org.flowable</pattern><shadedPattern>com.myapp.shaded.flowable</shadedPattern></relocation></relocations>
// after: keep org.flowable unshaded so ReflectUtil can instantiate DbUpgradeStep classes
<relocations/>
Defensive patterns

Strategy: try-catch

Validate before calling

try { Class.forName("org.flowable.common.engine.impl.db.DbUpgradeStep"); } catch (ClassNotFoundException e) { throw new IllegalStateException("Flowable internal db classes missing from classpath"); }

Try / catch

try { engineCfg.buildProcessEngine(); } catch (FlowableException e) { if (e.getMessage().contains("can't be instantiated")) { log.error("Upgrade step class issue: {}", e.getCause(), e.getCause()); } throw e; }

Prevention

When it happens

Trigger: Running a database upgrade script containing an 'execute java' directive whose class cannot be found on the classpath or cannot be instantiated — e.g. during dbSchemaUpgrade between specific Flowable versions.

Common situations: Custom jars excluding internal upgrade classes; classpath conflicts with different Flowable versions; shading/relocation that renames upgrade step classes; upgrading from a very old version where referenced classes changed packages.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/8befabe1c1ac4a86. Report an issue: GitHub.