{"record":{"id":"b45f3b56c6cc61a7","repo":"flowable/flowable-engine","slug":"failed-to-read-resource-resource-b45f3b","errorCode":null,"errorMessage":"Failed to read resource ${resource}","messagePattern":"Failed to read resource (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"modules/flowable-spring-boot/flowable-spring-boot-starters/flowable-spring-boot-autoconfigure/src/main/java/org/flowable/spring/boot/aot/process/FlowableProcessAutoDeployBeanFactoryInitializationAotProcessor.java","lineNumber":93,"sourceCode":"\n    static class ProcessAutoDeployResourceContribution extends BaseAutoDeployResourceContribution {\n\n        protected final ConfigurableListableBeanFactory beanFactory;\n\n        public ProcessAutoDeployResourceContribution(String locationPrefix, Collection<String> locationSuffixes, ConfigurableListableBeanFactory beanFactory) {\n            super(locationPrefix, locationSuffixes);\n            this.beanFactory = beanFactory;\n        }\n\n        @Override\n        protected void applyToResource(ClassPathResource resource, RuntimeHints hints) {\n            super.applyToResource(resource, hints);\n            BpmnXMLConverter xmlConverter = new BpmnXMLConverter();\n            BpmnModel bpmnModel = xmlConverter.convertToBpmnModel(() -> {\n                try {\n                    return resource.getInputStream();\n                } catch (IOException e) {\n                    throw new UncheckedIOException(\"Failed to read resource \" + resource, e);\n                }\n            }, false, false);\n            Collection<ServiceTask> serviceTasks = bpmnModel.getMainProcess().findFlowElementsOfType(ServiceTask.class);\n            for (ServiceTask serviceTask : serviceTasks) {\n                if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(serviceTask.getImplementationType())) {\n                    String expression = serviceTask.getImplementation();\n                    String expressionWithoutDelimiters = expression.substring(2);\n                    expressionWithoutDelimiters = expressionWithoutDelimiters.substring(0, expressionWithoutDelimiters.length() - 1);\n                    String beanName = expressionWithoutDelimiters;\n                    try {\n                        BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);\n                        String beanClassName = beanDefinition.getBeanClassName();\n                        if (StringUtils.isNotEmpty(beanClassName)) {\n                            hints.reflection().registerType(TypeReference.of(beanClassName), MemberCategory.values());\n                            logger.debug(\"Registering hint for bean name [{}] for service task {} in {}\", beanName, serviceTask.getId(), resource);\n                        } else {\n                            logger.debug(\"No bean class name for bean name [{}] for service task {} in {}\", beanName, serviceTask.getId(), resource);\n                        }","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-spring-boot/flowable-spring-boot-starters/flowable-spring-boot-autoconfigure/src/main/java/org/flowable/spring/boot/aot/process/FlowableProcessAutoDeployBeanFactoryInitializationAotProcessor.java#L75-L111","documentation":"During Spring AOT processing, FlowableProcessAutoDeployBeanFactoryInitializationAotProcessor.applyToResource parses each auto-deploy BPMN resource with BpmnXMLConverter to detect delegate-expression service tasks and register reflection hints. If resource.getInputStream() throws IOException it is wrapped as UncheckedIOException 'Failed to read resource <resource>'. The BPMN file exists on the classpath but its stream cannot be opened.","triggerScenarios":"AOT/native-image build where the converter's supplier calls getInputStream() on a classpath .bpmn/.bpmn20.xml resource and IO fails (broken jar entry, unavailable nested resource, permission error).","commonSituations":"GraalVM native builds on CI with inconsistent artifacts; corrupted target jar after interrupted build; resources inside nested jars; restrictive file permissions.","solutions":["Run a clean rebuild (mvn clean install) so the jar containing the BPMN files is consistent","Verify BPMN resources are present and readable in the artifact (jar tf / unzip -t)","Check file permissions and disk space on the build machine","Ensure Spring Boot AOT and Flowable versions are compatible and current"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"ClassPathResource r = new ClassPathResource(\"processes/my-process.bpmn20.xml\");\nif (!r.exists() || !r.getFile().canRead()) {\n    throw new IllegalStateException(\"BPMN resource missing or unreadable: \" + r);\n}","typeGuard":null,"tryCatchPattern":"try (InputStream in = resource.getInputStream()) {\n    // parse bpmn model\n} catch (UncheckedIOException | IOException e) {\n    logger.error(\"Cannot read BPMN resource {}\", resource, e);\n}","preventionTips":["Run mvn clean before release/AOT builds to prevent corrupted jars","Verify BPMN resources inside the built artifact, not just in src","Keep Spring Boot AOT and Flowable plugin versions aligned"],"tags":["aot","native-image","bpmn","io","resource"],"backgroundTag":"file-read-failed","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"}