When to read the code¶
First, a distinction that matters¶
Microflows are not source code. They are a model — nodes, edges and expressions, closer
to BPMN than to a .java file. Nothing draws them but Studio Pro, and nothing stores them but
binary units inside the .mpr. There is no file to open, and asking for "the source of a
microflow" has no answer.
That is not a gap, because their logic is completely available anyway. The extract holds every step, every branch and every expression verbatim — 162,883 steps and 156,891 branches — which is exactly what the deep dives quote when they write [24] and paste a condition. When this documentation says "the working rules", that is where they come from.
What is text, and therefore has a source file to read:
| Where it lives | Readable as | |
|---|---|---|
| Microflows, nanoflows, pages, domain model, security | the Mendix model | steps, branches, expressions — in model |
| Java actions | source/javasource |
1,286 .java files |
| JavaScript actions | source/javascriptsource |
text |
| Theme, styling, resources | source/theme, themesource, resources |
text |
So the two halves answer different questions. The model says what runs, in what order, under which condition, and who can trigger it. The source says what the code does once a flow hands over.
How often that hand-off happens¶
| measure | value |
|---|---|
| flows that call Java or JavaScript | 1018 |
| call sites in those flows | 1997 |
| actions with a source file | 632 |
| source files in total | 2482 |
| Java files using JDBC directly | 19 |
| files building names at runtime | 19 |
| literal microflow names found in Java | 1 |
Six reasons to open the code¶
1. A flow calls an action and the step tells you nothing. JAVA
DataManagement.jaImportCSV_BookingChanges($dir) is the whole model-side story. The file is 280
lines, parses CSV, and touches two entities.
2. The code goes around Mendix entirely. Thirteen Java files use JDBC. For those there is no
RETRIEVE and no CHANGE to find, because the data layer was never involved — the model cannot
describe what they read or write, and no amount of querying it will help.
3. Names are built at runtime. Java calls microflows through variables here, not literals:
Core.microflowCall(this.Microflow). Exactly one literal microflow name appears across all
1,286 Java files, so the Java → microflow direction is essentially absent from any static read.
If a trace looks suspiciously shallow at a Java boundary, this is why.
4. A commit from Java may not behave like a commit from a flow. Twenty files call
Core.commit, and the 52 entity events documented under
detailed lines hang off commits. Whether a particular
Java commit fires them is a property of the call, not of the model.
5. A shared action's behaviour matters more than its popularity. The model gives the caller count; only the file gives the semantics.
| action | lines | callers | entities_named |
|---|---|---|---|
| DataWidgets.Export_To_Excel | 83 | 138 | 0 |
| DataManagement.jaLog | 141 | 60 | 1 |
| CommunityCommons.Delay | 56 | 52 | 0 |
| Tools.jaGetMicroflowName | 53 | 42 | 0 |
| CommunityCommons.RandomHash | 47 | 36 | 0 |
| CommunityCommons.executeMicroflowInBackground | 69 | 31 | 0 |
| Tools.jaFinishInboundApiMetric | 53 | 19 | 0 |
| Tools.jaStartInboundApiMetric | 52 | 19 | 0 |
| CommunityCommons.GetApplicationUrl | 47 | 17 | 0 |
| XLSReport.GenerateExcelDoc | 235 | 16 | 0 |
| CommunityCommons.DuplicateFileDocument | 70 | 15 | 0 |
| CommunityCommons.Base64Encode | 53 | 13 | 0 |
the model gives the caller count; only the file gives the behaviour.
6. Integration detail. Endpoints, authentication and payload shaping are written in Java. The model names the mapping; the code holds the contract.
The places the model is blind¶
Not a warning in the abstract — this is the list.
| path | action | callers | why |
|---|---|---|---|
| source/javasource/xlsreport/actions/GenerateExcelDoc.java | XLSReport.GenerateExcelDoc | 16 | 2 runtime XPath |
| source/javasource/externaldatabaseconnector/actions/ExecuteQuery.java | DatabaseConnector.ExecuteQuery | 6 | raw SQL |
| source/javasource/enumentitybuilder/actions/jaBuildEnumerationMapping.java | EnumEntityBuilder.jaBuildEnumerationMapping | 3 | 1 runtime XPath |
| source/javasource/datamanagement/actions/jaInsertTPBookingLine.java | DataManagement.jaInsertTPBookingLine | 2 | raw SQL |
| source/javasource/datamanagement/actions/jaImportCSV_StaffRemuneration_B2C.java | DataManagement.jaImportCSV_StaffRemuneration_B2C | 1 | 1 runtime XPath |
| source/javasource/datamanagement/actions/jaInsertTPBookingLine_Exploration.java | DataManagement.jaInsertTPBookingLine_Exploration | 1 | raw SQL |
| source/javasource/communitycommons/Misc.java | 0 | 1 runtime XPath | |
| source/javasource/communitycommons/XPath.java | 0 | 2 runtime XPath | |
| source/javasource/databaseconnector/actions/ExecuteParameterizedQuery.java | DatabaseConnector.ExecuteParameterizedQuery | 0 | raw SQL |
| source/javasource/databaseconnector/actions/ExecuteQuery.java | 0 | raw SQL | |
| source/javasource/databaseconnector/impl/JdbcConnectionManager.java | 0 | raw SQL | |
| source/javasource/databaseconnector/impl/JdbcConnector.java | 0 | raw SQL | |
| source/javasource/databaseconnector/impl/PreparedStatementCreatorImpl.java | 0 | raw SQL | |
| source/javasource/databaseconnector/interfaces/PreparedStatementCreator.java | 0 | raw SQL | |
| source/javasource/datamanagement/tools/mxWindow.java | 0 | raw SQL | |
| source/javasource/datamanagement/tools/spi.java | 0 | raw SQL | |
| source/javasource/datamanagement/tools/wishConnection.java | 0 | raw SQL | |
| source/javasource/excelimporter/reader/ExcelImporter.java | 0 | 1 runtime XPath | |
| source/javasource/excelimporter/reader/readers/ExcelReader.java | 0 | 2 runtime XPath | |
| source/javasource/externaldatabaseconnector/actions/ExecuteQuery.java | ExternalDatabaseConnector.ExecuteQuery | 0 | raw SQL |
| source/javasource/externaldatabaseconnector/database/impl/connection/JdbcConnectionManager.java | 0 | raw SQL | |
| source/javasource/externaldatabaseconnector/database/impl/dbschema/provider/MxQueryBasedSchemaInfoProvider.java | 0 | raw SQL | |
| source/javasource/externaldatabaseconnector/database/impl/service/MxExecuteDmlQuery.java | 0 | raw SQL | |
| source/javasource/externaldatabaseconnector/database/impl/service/MxExecuteSelectQuery.java | 0 | raw SQL | |
| source/javasource/externaldatabaseconnector/database/impl/statement/PreparedStatementCreatorImpl.java | 0 | raw SQL |
JDBC bypasses the Mendix data layer entirely, so no RETRIEVE or CHANGE step exists to find; runtime-built names are edges no static read can follow.
A rule of thumb¶
Ask the model when the question is what happens, in what order, and who can start it. Ask the source when the question contains the word actually — "what does this actually do to the data", "why is this value actually wrong", "how exactly does it reach Tourplan".
Both are queryable from one place, including together: see asking Claude directly, or open the model explorer Java action actually do?*