{"record":{"id":"91d49088577e6563","repo":"flowable/flowable-engine","slug":"problem-retrieving-flowable-cfg-xml-resources-on-t-91d490","errorCode":null,"errorMessage":"problem retrieving flowable.cfg.xml resources on the classpath: ${classpath}","messagePattern":"problem retrieving flowable\\.cfg\\.xml resources on the classpath: (.+?)","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/ProcessEngines.java","lineNumber":78,"sourceCode":"    protected static Map<String, ProcessEngineInfo> processEngineInfosByResourceUrl = new HashMap<>();\n    protected static List<ProcessEngineInfo> processEngineInfos = new ArrayList<>();\n\n    /**\n     * 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\n     * <code>activiti-context.xml</code> (Spring style configuration).\n     */\n    public static synchronized void init() {\n        if (!isInitialized()) {\n            if (processEngines == null) {\n                // Create new map to store process-engines if current map is null\n                processEngines = new HashMap<>();\n            }\n            ClassLoader classLoader = ReflectUtil.getClassLoader();\n            Enumeration<URL> resources = null;\n            try {\n                resources = classLoader.getResources(\"flowable.cfg.xml\");\n            } catch (IOException e) {\n                throw new ActivitiIllegalArgumentException(\"problem retrieving flowable.cfg.xml resources on the classpath: \" + System.getProperty(\"java.class.path\"), e);\n            }\n\n            // Remove duplicated configuration URL's using set. Some classloaders may return identical URL's twice, causing duplicate startups\n            Set<URL> configUrls = new HashSet<>();\n            while (resources.hasMoreElements()) {\n                configUrls.add(resources.nextElement());\n            }\n            for (URL resource : configUrls) {\n                LOGGER.info(\"Initializing process engine using configuration '{}'\", resource);\n                initProcessEngineFromResource(resource);\n            }\n\n            try {\n                resources = classLoader.getResources(\"activiti-context.xml\");\n            } catch (IOException e) {\n                throw new ActivitiIllegalArgumentException(\"problem retrieving activiti-context.xml resources on the classpath: \" + System.getProperty(\"java.class.path\"), e);\n            }\n            while (resources.hasMoreElements()) {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/ProcessEngines.java#L60-L96","documentation":"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.","triggerScenarios":"Calling ProcessEngines.getDefaultProcessEngine()/init() when the thread context or ReflectUtil classloader fails to enumerate flowable.cfg.xml URLs (IOException from getResources).","commonSituations":"Unusual classloader setups: application servers with restricted classloading, OSGi containers, native-image or custom classloaders that throw on getResources.","solutions":["Inspect java.class.path and verify the app runs with a standard classloader","Check the container/classloader logs for the underlying IOException cause (e.getCause())","Load the engine explicitly via ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(\"flowable.cfg.xml\").buildProcessEngine() to bypass classpath scanning"],"exampleFix":"// before\nProcessEngine engine = ProcessEngines.getDefaultProcessEngine();\n// after\nProcessEngine engine = ProcessEngineConfiguration\n    .createProcessEngineConfigurationFromResource(\"flowable.cfg.xml\")\n    .buildProcessEngine();","handlingStrategy":"fallback","validationCode":"try {\n  ClassLoader cl = ReflectUtil.getClassLoader();\n  if (!cl.getResources(\"flowable.cfg.xml\").hasMoreElements())\n    log.warn(\"no flowable.cfg.xml on classpath\");\n} catch (IOException e) {\n  log.error(\"classpath enumeration broken\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  engine = ProcessEngines.getDefaultProcessEngine();\n} catch (ActivitiIllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"problem retrieving flowable.cfg.xml\"))\n    engine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(\"flowable.cfg.xml\").buildProcessEngine();\n  else throw e;\n}","preventionTips":["Place flowable.cfg.xml at the classpath root","Avoid exotic classloaders for engine bootstrap; prefer explicit configuration builders","Verify the java.class.path in the deployment environment"],"tags":["classpath","initialization","flowable","engine-config"],"backgroundTag":"file-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}