flowable/flowable-engine · error · ActivitiIllegalArgumentException

problem retrieving flowable.cfg.xml resources on the classpa

Error message

problem retrieving flowable.cfg.xml resources on the classpath: ${classpath}

What it means

ProcessEngines.init scans the classpath for flowable.cfg.xml resources; if ClassLoader.getResources throws IOException the initialization aborts with this ActivitiIllegalArgumentException including the java.class.path. It signals a classloading environment problem, not a bad config file.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/ProcessEngines.java:78

    protected static Map<String, ProcessEngineInfo> processEngineInfosByResourceUrl = new HashMap<>();
    protected static List<ProcessEngineInfo> processEngineInfos = new ArrayList<>();

    /**
     * Initializes all process engines that can be found on the classpath for resources <code>flowable.cfg.xml</code> (plain Activiti style configuration) and for resources
     * <code>activiti-context.xml</code> (Spring style configuration).
     */
    public static synchronized void init() {
        if (!isInitialized()) {
            if (processEngines == null) {
                // Create new map to store process-engines if current map is null
                processEngines = new HashMap<>();
            }
            ClassLoader classLoader = ReflectUtil.getClassLoader();
            Enumeration<URL> resources = null;
            try {
                resources = classLoader.getResources("flowable.cfg.xml");
            } catch (IOException e) {
                throw new ActivitiIllegalArgumentException("problem retrieving flowable.cfg.xml resources on the classpath: " + System.getProperty("java.class.path"), e);
            }

            // Remove duplicated configuration URL's using set. Some classloaders may return identical URL's twice, causing duplicate startups
            Set<URL> configUrls = new HashSet<>();
            while (resources.hasMoreElements()) {
                configUrls.add(resources.nextElement());
            }
            for (URL resource : configUrls) {
                LOGGER.info("Initializing process engine using configuration '{}'", resource);
                initProcessEngineFromResource(resource);
            }

            try {
                resources = classLoader.getResources("activiti-context.xml");
            } catch (IOException e) {
                throw new ActivitiIllegalArgumentException("problem retrieving activiti-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e);
            }
            while (resources.hasMoreElements()) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect java.class.path and verify the app runs with a standard classloader
  2. Check the container/classloader logs for the underlying IOException cause (e.getCause())
  3. Load the engine explicitly via ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("flowable.cfg.xml").buildProcessEngine() to bypass classpath scanning

Example fix

// before
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// after
ProcessEngine engine = ProcessEngineConfiguration
    .createProcessEngineConfigurationFromResource("flowable.cfg.xml")
    .buildProcessEngine();
Defensive patterns

Strategy: fallback

Validate before calling

try {
  ClassLoader cl = ReflectUtil.getClassLoader();
  if (!cl.getResources("flowable.cfg.xml").hasMoreElements())
    log.warn("no flowable.cfg.xml on classpath");
} catch (IOException e) {
  log.error("classpath enumeration broken", e);
}

Try / catch

try {
  engine = ProcessEngines.getDefaultProcessEngine();
} catch (ActivitiIllegalArgumentException e) {
  if (e.getMessage().startsWith("problem retrieving flowable.cfg.xml"))
    engine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("flowable.cfg.xml").buildProcessEngine();
  else throw e;
}

Prevention

When it happens

Trigger: Calling ProcessEngines.getDefaultProcessEngine()/init() when the thread context or ReflectUtil classloader fails to enumerate flowable.cfg.xml URLs (IOException from getResources).

Common situations: Unusual classloader setups: application servers with restricted classloading, OSGi containers, native-image or custom classloaders that throw on getResources.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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