Description
We encountered a BPMN schema validation failure in Flowable 7.2.0 when the Flowable dependency jar is loaded from an unpacked Spring Boot executable jar located under a path containing non-ASCII characters.
The BPMN XML itself is valid. The failure happens during Flowable's default BPMN schema validation.
Environment
- Flowable:
7.2.0
- Spring Boot:
3.2.12
- Deployment style: unpacked executable jar, started with
org.springframework.boot.loader.launch.JarLauncher
- Java: reproduced on Java 17 / Java 21
- OS: Windows
- Runtime path contains non-ASCII characters, for example:
D:/workspace/流程/runtime/.runtime.jar.exploded/BOOT-INF/lib/flowable-bpmn-converter-7.2.0.jar
Why the classpath contains non-ASCII characters
Our application uses Spring Boot's efficient deployment style by unpacking the executable jar before startup.
This is similar to the deployment approach described in the Spring Boot reference documentation:
https://docs.spring.io/spring-boot/docs/3.2.12/reference/html/deployment.html#deployment.efficient.unpacking
In this mode, the executable jar is exploded and the application is started from the unpacked directory. The runtime classpath then contains entries such as:
<workspace>/runtime/.runtime.jar.exploded/BOOT-INF/classes
<workspace>/runtime/.runtime.jar.exploded/BOOT-INF/lib/*
We use this deployment mode mainly to improve cold startup time.
The <workspace> directory is user-controlled. In desktop, local-runtime, or embedded-runtime scenarios, this directory can naturally contain localized names, for example:
D:/workspace/流程/runtime/.runtime.jar.exploded/BOOT-INF/lib/flowable-bpmn-converter-7.2.0.jar
Therefore, the Flowable dependency jar becomes part of a classpath whose physical path contains non-ASCII characters.
This is not related to the BPMN file name or BPMN content. It is a consequence of running a valid Spring Boot unpacked deployment from a localized workspace path.
Actual Error From Our Application
Application-specific package names and local paths are anonymized below, but the Flowable, Spring Boot, JDK, and Xerces stack frames are unchanged.
2026-06-02 13:32:08.701 [main] ERROR o.f.e.impl.bpmn.deployer.ParsedDeploymentBuilder - Could not parse resource process1.bpmn
org.flowable.bpmn.exceptions.XMLException: src-resolve: Cannot resolve the name 'extension' to a(n) 'element declaration' component.
at org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:292)
at org.flowable.engine.impl.bpmn.parser.BpmnParse.execute(BpmnParse.java:148)
at org.flowable.engine.impl.bpmn.deployer.ParsedDeploymentBuilder.createBpmnParseFromResource(ParsedDeploymentBuilder.java:97)
at org.flowable.engine.impl.bpmn.deployer.ParsedDeploymentBuilder.build(ParsedDeploymentBuilder.java:55)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:78)
at org.flowable.engine.impl.persistence.deploy.DeploymentManager.deploy(DeploymentManager.java:62)
at org.flowable.engine.impl.cmd.DeployCmd.executeDeploy(DeployCmd.java:135)
at org.flowable.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:70)
at org.flowable.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:45)
at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:75)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:199)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:128)
at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:80)
at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:26)
at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53)
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:105)
at org.flowable.common.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:57)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:57)
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56)
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51)
at org.flowable.engine.impl.RepositoryServiceImpl.deploy(RepositoryServiceImpl.java:99)
at org.flowable.engine.impl.repository.DeploymentBuilderImpl.deploy(DeploymentBuilderImpl.java:206)
at com.example.runtime.process.service.ProcessDeployService.deployProcess(ProcessDeployService.java:140)
at com.example.runtime.process.service.ProcessDeployService.deployProcesses(ProcessDeployService.java:112)
at com.example.runtime.process.service.ProcessDeployService.deployAndCacheProcesses(ProcessDeployService.java:81)
at com.example.runtime.process.config.FlowableAutoConfiguration.buildAndStartEngine(FlowableAutoConfiguration.java:247)
at com.example.runtime.process.config.FlowableAutoConfiguration.initialize(FlowableAutoConfiguration.java:112)
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:383)
at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:255)
at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:174)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:455)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:388)
at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:109)
at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:80)
at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:80)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:332)
at com.example.runtime.Application.main(Application.java:27)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:106)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64)
at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40)
Caused by: org.xml.sax.SAXParseException; systemId: jar:file:/D:/workspace/流程/runtime/.runtime.jar.exploded/BOOT-INF/lib/flowable-bpmn-converter-7.2.0.jar!/org/flowable/impl/bpmn/parser/BPMN20.xsd; lineNumber: 15; columnNumber: 70; src-resolve: Cannot resolve the name 'extension' to a(n) 'element declaration' component.
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:135)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:396)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4254)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4237)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1791)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(XSDElementTraverser.java:170)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseLocalElements(XSDHandler.java:3707)
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:543)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:281)
at java.xml/javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:612)
at java.xml/javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:644)
at org.flowable.bpmn.converter.BpmnXMLConverter.createSchema(BpmnXMLConverter.java:252)
at org.flowable.bpmn.converter.BpmnXMLConverter.validateModel(BpmnXMLConverter.java:231)
at org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:283)
... 51 common frames omitted
Minimal Reproduction
The following minimal Spring Boot application uses Flowable in the normal way. It does not manually load BPMN20.xsd and does not configure a custom classloader. It only calls Flowable's default BPMN XML conversion with schema validation enabled.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.12</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>flowable-non-ascii-classpath-repro</artifactId>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-bpmn-converter</artifactId>
<version>7.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
src/main/java/com/example/repro/FlowableNonAsciiClasspathReproApplication.java
package com.example.repro;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.common.engine.api.io.InputStreamProvider;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@SpringBootApplication
public class FlowableNonAsciiClasspathReproApplication implements CommandLineRunner {
private static final String BPMN_XML = """
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://example.com/process">
<process id="process1" isExecutable="true">
<startEvent id="start" />
</process>
</definitions>
""";
public static void main(String[] args) {
SpringApplication.run(FlowableNonAsciiClasspathReproApplication.class, args);
}
@Override
public void run(String... args) {
BpmnXMLConverter converter = new BpmnXMLConverter();
converter.convertToBpmnModel(new BpmnInputStreamProvider(), true, false);
System.out.println("Flowable BPMN XML conversion succeeded");
}
private static class BpmnInputStreamProvider implements InputStreamProvider {
@Override
public InputStream getInputStream() {
return new ByteArrayInputStream(BPMN_XML.getBytes(StandardCharsets.UTF_8));
}
}
}
reproduce.ps1
param(
[string]$WorkDir = "$env:TEMP\flowable-repro-流程"
)
$ErrorActionPreference = "Stop"
mvn -DskipTests package
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
Remove-Item -Recurse -Force $WorkDir -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Path $WorkDir | Out-Null
Copy-Item ".\target\flowable-non-ascii-classpath-repro-1.0.0.jar" "$WorkDir\app.jar"
Push-Location $WorkDir
try {
jar -xf app.jar
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
java org.springframework.boot.loader.launch.JarLauncher
exit $LASTEXITCODE
}
finally {
Pop-Location
}
How to Run the Reproduction
From the reproduction project directory:
pwsh -NoProfile -File .\reproduce.ps1
The script creates an unpacked runtime layout like:
%TEMP%\flowable-repro-流程\BOOT-INF\classes
%TEMP%\flowable-repro-流程\BOOT-INF\lib\flowable-bpmn-converter-7.2.0.jar
Reproduction Output
Starting FlowableNonAsciiClasspathReproApplication v1.0.0 using Java 21.0.6
(C:\Users\<user>\AppData\Local\Temp\flowable-repro-流程\BOOT-INF\classes started by <user>
in C:\Users\<user>\AppData\Local\Temp\flowable-repro-流程)
org.flowable.bpmn.exceptions.XMLException: src-resolve: Cannot resolve the name 'extension' to a(n) 'element declaration' component.
at org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:292) ~[flowable-bpmn-converter-7.2.0.jar:7.2.0]
at org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:262) ~[flowable-bpmn-converter-7.2.0.jar:7.2.0]
at com.example.repro.FlowableNonAsciiClasspathReproApplication.run(FlowableNonAsciiClasspathReproApplication.java:34) ~[classes/:1.0.0]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) ~[spring-boot-3.2.12.jar:3.2.12]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:774) ~[spring-boot-3.2.12.jar:3.2.12]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:342) ~[spring-boot-3.2.12.jar:3.2.12]
at com.example.repro.FlowableNonAsciiClasspathReproApplication.main(FlowableNonAsciiClasspathReproApplication.java:28) ~[classes/:1.0.0]
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:102) ~[flowable-repro-%e6%b5%81%e7%a8%8b/:na]
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64) ~[flowable-repro-%e6%b5%81%e7%a8%8b/:na]
at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40) ~[flowable-repro-%e6%b5%81%e7%a8%8b/:na]
Caused by: org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'extension' to a(n) 'element declaration' component.
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:135) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:396) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4254) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4237) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1791) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(XSDElementTraverser.java:170) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseLocalElements(XSDHandler.java:3707) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:666) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:618) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:577) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:543) ~[na:na]
at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:281) ~[na:na]
at java.xml/javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:612) ~[na:na]
at java.xml/javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:644) ~[na:na]
at org.flowable.bpmn.converter.BpmnXMLConverter.createSchema(BpmnXMLConverter.java:252) ~[flowable-bpmn-converter-7.2.0.jar:7.2.0]
at org.flowable.bpmn.converter.BpmnXMLConverter.validateModel(BpmnXMLConverter.java:231) ~[flowable-bpmn-converter-7.2.0.jar:7.2.0]
at org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:283) ~[flowable-bpmn-converter-7.2.0.jar:7.2.0]
... 27 common frames omitted
Observed Behavior
When the Flowable jar is loaded from an unpacked Spring Boot classpath under a non-ASCII directory, Flowable's default BPMN XML conversion fails during schema validation.
The failure occurs inside:
org.flowable.bpmn.converter.BpmnXMLConverter.createSchema
org.flowable.bpmn.converter.BpmnXMLConverter.validateModel
org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel
Expected Behavior
Flowable should be able to load and validate its built-in BPMN schema resources from classpath jars even when the jar path contains non-ASCII characters.
Non-ASCII classpath locations are valid in localized user environments and should not prevent BPMN deployment or schema validation.
Description
We encountered a BPMN schema validation failure in Flowable
7.2.0when the Flowable dependency jar is loaded from an unpacked Spring Boot executable jar located under a path containing non-ASCII characters.The BPMN XML itself is valid. The failure happens during Flowable's default BPMN schema validation.
Environment
7.2.03.2.12org.springframework.boot.loader.launch.JarLauncherWhy the classpath contains non-ASCII characters
Our application uses Spring Boot's efficient deployment style by unpacking the executable jar before startup.
This is similar to the deployment approach described in the Spring Boot reference documentation:
https://docs.spring.io/spring-boot/docs/3.2.12/reference/html/deployment.html#deployment.efficient.unpacking
In this mode, the executable jar is exploded and the application is started from the unpacked directory. The runtime classpath then contains entries such as:
We use this deployment mode mainly to improve cold startup time.
The
<workspace>directory is user-controlled. In desktop, local-runtime, or embedded-runtime scenarios, this directory can naturally contain localized names, for example:Therefore, the Flowable dependency jar becomes part of a classpath whose physical path contains non-ASCII characters.
This is not related to the BPMN file name or BPMN content. It is a consequence of running a valid Spring Boot unpacked deployment from a localized workspace path.
Actual Error From Our Application
Application-specific package names and local paths are anonymized below, but the Flowable, Spring Boot, JDK, and Xerces stack frames are unchanged.
Minimal Reproduction
The following minimal Spring Boot application uses Flowable in the normal way. It does not manually load
BPMN20.xsdand does not configure a custom classloader. It only calls Flowable's default BPMN XML conversion with schema validation enabled.pom.xmlsrc/main/java/com/example/repro/FlowableNonAsciiClasspathReproApplication.javareproduce.ps1How to Run the Reproduction
From the reproduction project directory:
The script creates an unpacked runtime layout like:
Reproduction Output
Observed Behavior
When the Flowable jar is loaded from an unpacked Spring Boot classpath under a non-ASCII directory, Flowable's default BPMN XML conversion fails during schema validation.
The failure occurs inside:
Expected Behavior
Flowable should be able to load and validate its built-in BPMN schema resources from classpath jars even when the jar path contains non-ASCII characters.
Non-ASCII classpath locations are valid in localized user environments and should not prevent BPMN deployment or schema validation.