{"record":{"id":"29fa97dfcfeef1ea","repo":"flowable/flowable-engine","slug":"invalid-url-resourceurl-29fa97","errorCode":null,"errorMessage":"invalid url: ${resourceUrl}","messagePattern":"invalid url: (.+?)","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/ProcessEngines.java","lineNumber":224,"sourceCode":"     *\n     * @param processEngineName is the name of the process engine or null for the default process engine.\n     */\n    public static ProcessEngine getProcessEngine(String processEngineName) {\n        if (!isInitialized()) {\n            init();\n        }\n        return processEngines.get(processEngineName);\n    }\n\n    /**\n     * retries to initialize a process engine that previously failed.\n     */\n    public static ProcessEngineInfo retry(String resourceUrl) {\n        LOGGER.debug(\"retying initializing of resource {}\", resourceUrl);\n        try {\n            return initProcessEngineFromResource(new URL(resourceUrl));\n        } catch (MalformedURLException e) {\n            throw new ActivitiIllegalArgumentException(\"invalid url: \" + resourceUrl, e);\n        }\n    }\n\n    /**\n     * provides access to process engine to application clients in a managed server environment.\n     */\n    public static Map<String, ProcessEngine> getProcessEngines() {\n        return processEngines;\n    }\n\n    /**\n     * closes all process engines. This method should be called when the server shuts down.\n     */\n    public static synchronized void destroy() {\n        if (isInitialized()) {\n            Map<String, ProcessEngine> engines = new HashMap<>(processEngines);\n            processEngines = new HashMap<>();\n","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/ProcessEngines.java#L206-L242","documentation":"ProcessEngines.retry() re-attempts engine initialization from a resource URL string. It parses the string with new URL(resourceUrl); if the string is not a well-formed URL (MalformedURLException), it throws ActivitiIllegalArgumentException wrapping the original message. This happens when the activiti/flowable engine name file (flowable.cfg.xml style resources declared in EngineConfigurationsResourceResolver / flowable-engine.properties or a system property pointing to engine configurations) contains an entry that is not a valid absolute URL.","triggerScenarios":"Calling ProcessEngines.retry(resourceUrl) with a string that is not a parseable URL, e.g. a bare classpath-style path, a plain file name, a path with illegal characters, or a malformed URL missing protocol/containing spaces.","commonSituations":"Manual edits to flowable-engine.properties / engine configuration resource listings; passing a classpath resource like 'flowable.cfg.xml' instead of a URL; typos in a custom ProcessEngineInfo registration; misconfigured container environments where a resource path is meant to be a file location not a URL.","solutions":["Fix the resource string to be a well-formed absolute URL, e.g. file:/path/to/flowable.cfg.xml or jar:file:...!/flowable.cfg.xml.","If the engine config is on the classpath, use ProcessEngines.getDefaultProcessEngine() or initProcessEngineFromResource with a classloader-derived URL (ClassLoader.getResource(name)) instead of a raw path.","Validate with new URL(resourceUrl) in a try/catch (or java.net.URI.create) before passing to retry to get a clearer failure point.","Check that flowable-engine.properties entries and any custom resource declarations were not corrupted by build/deployment tooling."],"exampleFix":"// before\nProcessEngines.retry(\"flowable.cfg.xml\"); // MalformedURLException\n// after\njava.net.URL url = ProcessEngines.class.getClassLoader().getResource(\"flowable.cfg.xml\");\nProcessEngines.retry(url.toString()); // e.g. file:/app/classes/flowable.cfg.xml","handlingStrategy":"validation","validationCode":"if (resourceUrl == null || !resourceUrl.matches(\"^[a-zA-Z][a-zA-Z0-9+.-]*:.*\")) {\n    throw new IllegalArgumentException(\"Not a valid URL for engine resource: \" + resourceUrl);\n}","typeGuard":null,"tryCatchPattern":"try { return ProcessEngines.retry(resourceUrl); } catch (ActivitiIllegalArgumentException e) { logger.error(\"Bad engine resource URL\", e); throw new ConfigException(e); }","preventionTips":["Always derive resource URLs via ClassLoader.getResource(), never hand-write them","Validate with new URI(resourceUrl) in config loading tests","Keep engine resource property files under review in CI"],"tags":["configuration","url","engine-initialization","illegal-argument"],"backgroundTag":"invalid-url-format","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}