Activiti integration
State on this dev DB: engine wired, never used. The Activiti engine is fully bootstrapped at runtime, the
act_*schema is provisioned, the BPMN modeler UI is reachable — but every workflow-related table is empty. No BPMN deployed, no process instances ever started, nogdsmodulerow currently hasbCheck = 1. The plumbing is hot; nothing is flowing.
This page documents what's actually wired (concrete classes, URLs, engine state) and what would have to be true for it to do anything.
Activiti is wired — engine ON
Despite the dev DB being idle, the engine boots with xlyEntry:
-
xlyFlow/build.gradle:15pullsorg.activiti:activiti-spring-boot-starter-rest-api:6.0.0. That starter transitively pullsactiviti-spring-boot-starter, which triggers Spring Boot'sProcessEngineAutoConfigurationto create aSpringProcessEngineConfigurationbean. -
xlyEntry/build.gradleincludesxlyFlowasapi project(':xlyFlow'), so the starter is on the runtime classpath of thexlyEntryWAR. -
xlyEntry/.../EntryApplicationBoot.java:23-24excludes onlyorg.activiti.spring.boot.SecurityAutoConfiguration(the REST-endpoint security adapter) and Spring's ownSecurityAutoConfiguration. Activiti's main engine auto-config is NOT excluded → the engine starts. -
xlyFlow/.../activiti/config/ActivitiConfig.javais a@Configuration implements ProcessEngineConfigurationConfigurerwhose only job is to set Chinese-friendly fonts on the diagram generator (宋体for activity / annotation / label fonts) and install a customICustomProcessDiagramGenerator. -
xlyApi'sApiApplicationBootdoes NOT exclude Activiti either, but xlyApi doesn't include xlyFlow as a dep, so xlyApi has the engine'sorg.activiti.engine.identity.Userclass on classpath (used only byIdGen.javafor crypto utilities) but no Activiti auto-config kicks in there.
The 24 base act_* tables you see in the live schema are created by
the engine's auto-DDL on first boot.
Two Activiti versions on the classpath
| Module | Version | Notes |
|---|---|---|
xlyPersist, xlyApi
|
org.activiti:activiti-engine:5.17.0 |
Older 5.x line — declared in both modules. Vestigial — the runtime engine in xlyEntry's WAR is the 6.0 one pulled by xlyFlow's starter. The 5.17 declarations are dead weight on the classpath. |
xlyFlow |
org.activiti:activiti-spring-boot-starter-rest-api:6.0.0, activiti-json-converter:6.0.0
|
Newer 6.0 line — this is what runs. |
A maintainer cleaning up should drop 5.17.0 from xlyPersist and
xlyApi's build.gradle. Verified: only IdGen.java in each of
those modules touches org.activiti.engine.identity.User, and the
type signature is satisfied by the 6.0 engine too — removal is safe.
What's actually invoked from code
The 154 Java files under xlyFlow/src/main/java/com/xly/activiti/
plus the modeler subpackage are real call sites. Selected anchors:
| Activity | Class : line | Activiti API used |
|---|---|---|
| Start a process instance |
ProcessServiceImpl.submitApply() :107 |
runtimeService.startProcessInstanceByKey(module, businessKey, variables) |
| Complete a task |
CurrencyFlowController.complete(...) :167 / :200; WechatFlowPostThread :132 |
processService.complete(taskId, ...) → taskService.complete()
|
| Query active tasks |
CurrencyFlowController :409, :480 |
taskService.createTaskQuery().active().list() |
| Query running instances |
CurrencyFlowController :485, :659 |
runtimeService.createProcessInstanceQuery() |
| Save a model in the modeler |
ModelerController.create() :122 |
repositoryService.saveModel() + addModelEditorSource()
|
| Deploy a BPMN at runtime |
ModelerController.deploy() :147 |
repositoryService.createDeployment().addString(name, bpmnXml).deploy() |
| List process definitions |
ProcessDefinitionController :135 |
repositoryService.createProcessDefinitionQuery() |
| Read engine config |
ProcessActController :281 |
ProcessEngines.getDefaultProcessEngine() |
| Bridge xly users into Activiti identity |
act_id_user / act_id_group / act_id_membership are views projecting xly's sftlogininfo* schema |
xly does not write to Activiti's identity tables; the views fake them |
URLs the modeler exposes (xlyFlow controllers, on xlyEntry's port)
Because xlyFlow is consumed as a library by xlyEntry (api project(':xlyFlow')),
all xlyFlow controllers compile into the xlyEntry WAR and serve at
xlyEntry's context-path (/xlyEntry). Notable URLs:
-
POST /xlyEntry/modeler/model/{modelId}/save— save BPMN-modeler XML -
GET /xlyEntry/modeler/model/{modelId}/json— load model for editor -
GET /xlyEntry/modeler/editor/stencilset— modeler stencil definitions -
GET /xlyEntry/modeler/create//modeler/deploy/{modelId}— create + deploy -
POST /xlyEntry/complete/{taskId}/{sBrandsId}/{sSubsidiaryId}/{sUserId}— complete a task (CurrencyFlowController) -
POST /xlyEntry/completeerp/{sBrandsId}/{sSubsidiaryId}/{sUserName}— ERP-side completion variant
These are not catalogued on the Internal API page because they're rarely-touched workflow surface; treat the source as authoritative.
What CheckFlowController.java actually contains
This is a wiki-internal correction worth flagging: the class file
exists at xlyEntry/src/main/java/com/xly/web/businessweb/CheckFlowController.java
but its body is 22 lines, zero handler methods — just a
@RestController @RequestMapping(value="/checkflow") shell with no
content. Earlier versions of this wiki described /checkflow/* as
"Activiti workflow surface (approve / reject / view)"; that is not
what the file currently contains. /checkflow/* returns 404 for
any sub-path on the live system. The actual approve/reject/view
URLs come from CurrencyFlowController and friends listed above.
The act_* schema state (this dev DB)
| Table | Rows | Meaning when populated |
|---|---|---|
act_re_model |
0 | BPMN models saved in the modeler |
act_re_procdef |
0 | Deployed process definitions |
act_ru_task |
0 | Active (waiting) tasks |
act_hi_procinst |
0 | Historical process instances |
act_id_user / act_id_group / act_id_membership
|
(views) | Project xly's sftlogininfo* users into Activiti identity shape |
gdsmoduleflow |
0 | xly's link from gdsmodule to a process definition |
biz_flow |
0 | xly's per-document flow state |
biz_todo_item |
0 | Pending approver tasks (xly wrapper, not Activiti's act_ru_task) |
biz_todo_copyto |
0 | CC'd parties on a flow |
So Activiti is stone-cold idle. Engine running, schemas ready, no traffic.
What would make it move
For a flow to actually run, in roughly this order:
- An engineer or PM opens the modeler UI (modeler static assets at
xlyFlow/src/main/resources/static/modeler/, served via the/modeler/*endpoints). They draw a BPMN, save it (act_re_modelpopulated). - They click Deploy in the modeler →
ModelerController.deploy()callsrepositoryService.createDeployment().addString(name, bpmnXml).deploy()→act_re_procdefpopulated. - A
gdsmodulerow is taggedbCheck = 1and a row ingdsmoduleflowlinks the module to the deployedact_re_procdef.KEY_. - When a user saves a row on that module, the save service detects
bCheck = 1and callsProcessServiceImpl.submitApply(applyUserId, businessKey, itemName, itemContent, module, variables). That firesruntimeService.startProcessInstanceByKey(module, businessKey, variables)→act_ru_*tables populate,biz_flow+biz_todo_itemget xly-side rows. - Approvers see pending tasks in their FROUNT inbox (probably the
"审批" tab, separate from KPI Work Center). They click 通过/驳回 →
CurrencyFlowController.complete()→taskService.complete(). - When the proc instance reaches
endEvent, the row'sbChecktransitions; downstream queries that filter onbCheck = 1start seeing it.
Why xly bothered with Activiti at all
The codebase has its own biz_flow / biz_todo_item tables that
could implement a hand-rolled approval system. The decision to put
Activiti behind them buys:
- Standard BPMN modeling (the JS modeler pulls the same stencilset as Activiti Explorer).
- Free state-machine semantics — the engine handles "task A done → task B available" without xly maintaining the FSM in SQL.
- Diagram rendering (the page-as-PNG in
ProcessActController).
The cost: a second engine running in the JVM, a second DB schema with
its own DDL drift, a second authentication surface (which xly papers
over via the act_id_* views).
What this page is not
- A Slice 7 substitute. Slice 7 (deferred) would document an end-to-end traced flow against a deployment that actually runs one.
- A modeler tutorial. The modeler comes from the Activiti project; xly embeds it as static assets without modification.
- A migration plan from Activiti to anything else. That would be a larger architectural decision, not a wiki finding.