解决activiti流程部署时报错:not a valid value for 'NCName'

问题现象描述

项目中使用了activiti作为工作流引擎,为了使用更加方便,自己开发了一套流程设置功能。先构建BpmnModel对象,再使用RepositoryService提供的deploy方法动态部署到activiti中。

功能开发完成后,开发本地测试和一轮测试之前都是OK的。然后前几日,在回归测试的时候,出现了某些用户可以成功部署,某些用户无法成功部署的“奇怪”现象。观察后台无法部署的后台错误日志:

org.activiti.bpmn.exceptions.XMLException: cvc-datatype-valid.1.2.1: '0785bf15-8d5d-11e7-8f8f-5254004a5833_39abc790-91fa-11e7-9e50-5254004a5833_loan' is not a valid value for 'NCName'.
    at org.activiti.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:280)
    at org.activiti.engine.impl.bpmn.parser.BpmnParse.execute(BpmnParse.java:187)
    at org.activiti.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:136)
    at org.activiti.engine.impl.persistence.deploy.DeploymentManager.deploy(DeploymentManager.java:58)
    at org.activiti.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:106)
    at org.activiti.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:37)
    at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24)
    at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57)
    at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
    at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
    at org.activiti.engine.impl.RepositoryServiceImpl.deploy(RepositoryServiceImpl.java:79)
    at org.activiti.engine.impl.repository.DeploymentBuilderImpl.deploy(DeploymentBuilderImpl.java:156)
    at com.jinzay.platform.activiti.helper.service.ActivitiEngineService.repositoryDeployment(ActivitiEngineService.java:158)
    at com.jinzay.ees.mst.service.api.MstProcessConfigController.deploy(MstProcessConfigController.java:282)
    at com.jinzay.ees.mst.service.api.MstProcessConfigController$$FastClassBySpringCGLIB$$e14ce3a5.invoke()
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
    at com.jinzay.ees.mst.service.api.MstProcessConfigController$$EnhancerBySpringCGLIB$$f5ce0d0c.deploy()
    at sun.reflect.GeneratedMethodAccessor556.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:211)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:809)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: '0785bf15-8d5d-11e7-8f8f-5254004a5833_39abc790-91fa-11e7-9e50-5254004a5833_loan' is not a valid value for 'NCName'.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:396)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:284)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:452)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3230)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processOneAttribute(XMLSchemaValidator.java:2825)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processAttributes(XMLSchemaValidator.java:2762)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:2050)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:740)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:380)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2787)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:118)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.jaxp.validation.StreamValidatorHelper.validate(StreamValidatorHelper.java:155)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:116)
    at javax.xml.validation.Validator.validate(Validator.java:124)
    at org.activiti.bpmn.converter.BpmnXMLConverter.validateModel(BpmnXMLConverter.java:214)
    at org.activiti.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:269)
    ... 97 common frames omitted

问题解决过程

这个报错的意思大概是:

xml sechma校验中,字符串'0785bf15-8d5d-11e7-8f8f-5254004a5833_39abc790-91fa-11e7-9e50-5254004a5833_loan'不是合法的'NCName'类型。

于是想着百度看看NCName是什么类型,有什么约束。然后似乎没有一篇能说明白。试探了多次,发现:

原来是不能以数字开头

为了证实想法,借助谷歌终于弄清楚了。NCName只能以下划线(_)或字母开头,只能包含中划线(-)、下划线、字母和数字,我们的流程ID是按单位ID+'_'+部门ID规则拼接的,而单位ID是随机生成的字符串,所以有的是以数字开头的就无法部署。最终,我们更改了单位ID的 生成规则,保证是字母开头(多么简单粗暴的solution...)。

常用的XML内置类型

  1. XML Schema 内置简单类型:

    • string 字符数据类型

    模式处理器在处理string类型的值时,会将值中所有空白字符包括空格、制表符、回车换行都保留。

    • normalizedString

    派生自string,与string不同的地方:模式处理器对空白的处理方式,处理器会将读到的 每一个回车、换行和制表符替换为单个空格字符。

    • token

    派生自normalizedString,模式处理器对 于此类型的内容时,会用单个空格来替换读到的每一个回车、换行和制表符,替换后,每一组连续的空格被压缩为一个空格字符,而所有前导和后导空格被删除。

    • Name

    派生自token,它表示一个XML名称,即该类型的值必须以字母、下划线(_)或冒号(:)开头,而且只能包含字母、数字、连字符、下划线、冒号或句号(.)。

    • NCName

    继承自Name,表示一个XML无冒号的名称,即该名称中不能使用冒号。它与Name类似,唯一的区别就是不能使用冒号。

  2. 数字类型

    • float和double(单精度和双精度浮点数)

    float数据类型表示IEEE单精度32位浮点数,而double表示IEEEE双精度64位浮点数。

    • decimal

    数据类型decimal表示任意精度的小数,不同的模式处理器支持的有效位数是不一样的,不过XML Schema推荐标准中要求符合规范的模式处理器必须至少支持18位有效数字。

    • integer

    数据类型integer派生自decimal,表示一个任意大的整数。从integer数据类型派生了其他十二中内置的整数类型。

  3. 日期和时间类型

    • date

    用于表示日期。date的格式为:YYYY-MM-DD。要表示9999年之后的年份,在年值左边添加数字,但不允许前导0;表示公元前的年,可以在年值钱添加负号-。可以在日期值之后添加时区表达式,或者字母‘Z’,表示UTC时间。

    • time

    表示时间。time的格式是:hh:mm:ss.sss。时间是24小时制。可以在时间值之后添加可选的时间表达式,或者添加字母‘Z’,表示是UTC时间。

    • dateTime

    表示完整的日期和时间,即date+time,本类型的格式为YYYY-MM-DDThh:mm:ss.sss,字母T作为日期和时间的分割。可以在dateTime值之后添加可选的时区表达式,或者添加字符’Z’。

    • gYear

    表示一个特定的阳历年,格式为: YYYY

    • gYearMonth

    表示一个特定年的某月,格式: YYYY-MM

    • gMonth

    表示某个月,格式为: --MM

    • gMonthDay

    表示某个月的某天,格式: --MM-DD (8) gDay 表示某天,格式为: ---DD

    • duration

    表示持续时间。格式为:PnYnMnDTnHnMnS。 示例:P2Y3M4DT23H12M15.6S

  4. 其他数据类型

    • boolean

    表示逻辑值,有效值是true,false,0,1

    • anyURI

    表示一个统一资源标示符的引用。

    • QName

    表示XML名称空间限定名。Qname值包括一个名称空间前缀和本地部分(这两部分都是NCName类型),中间用冒号分隔。


参考

http://3y.uu456.com/bp_7sdqb2ylp82b61z989o0_1.html

你可能感兴趣的:(解决activiti流程部署时报错:not a valid value for 'NCName')