Repository navigation
create java action has no clause for the EXTRA CODE section and describe java action omits it: a describe round trip loses hand-written helpers (create or modify keeps them in place) #1658
Description
mxcli v0.28.0 (2026-10-23) · Mendix 11.14.0 (blank app) · Windows Server 2025
Summary
Studio Pro keeps three parts of a Java action's .java file when it regenerates it: the import list, the code
between BEGIN USER CODE / END USER CODE, and the code between BEGIN EXTRA CODE / END EXTRA CODE (helper
methods, constants, nested classes). MDL can author the first two (AS $$ … $$, and an import line in the body is
moved to the import list - nice), but has no clause for the EXTRA CODE section, and describe java action prints
only the body.
create or modify on an existing file correctly keeps a hand-written EXTRA CODE block, so nothing is lost in
place. But a script produced by describe is not a full round trip: executed on a fresh project (or wherever the
.java file is regenerated) it writes a body that calls a helper which no longer exists, and the project stops
compiling.
Minimal repro
ewo_ja1.mdl
create module ModJ;
create java action ModJ.JA_Twice(N: Integer not null) returns Integer
as $$
return N * 2L;
$$;- Hand-add a helper in the EXTRA CODE block of
javasource/modj/actions/JA_Twice.java(and an import), as the
file header says is retained:
// BEGIN EXTRA CODE
private static long twice(long n) { return n * 2L; }
// END EXTRA CODEewo_ja2.mdl- the file keeps the helper and the import (good):
create or modify java action ModJ.JA_Twice(N: Integer not null) returns Integer
as $$
return twice(N);
$$;mxcli -p Repro.mpr -c "describe java action ModJ.JA_Twice"prints:
mdl 1;
create or modify java action ModJ.JA_Twice(N: Integer not null) returns Integer as $ReturnValueName
as $$
return twice(N);
$$;- Fresh blank project:
create module ModJ;, then exec the describe output of step 4.JA_Twice.java:
// BEGIN USER CODE
return twice(N);
// END USER CODE
...
// BEGIN EXTRA CODE
// END EXTRA CODE
}twice(long) is undefined: the project no longer compiles.
Expected
describe prints everything Studio Pro retains, so that executing its output rebuilds the same file, and MDL can
author it - for example (any spelling):
create or modify java action ModJ.JA_Twice(N: Integer not null) returns Integer
as $$
return twice(N);
$$
extra $$
private static long twice(long n) { return n * 2L; }
$$;Actual
mxcli syntax java-action.createhas no clause for the EXTRA CODE section;describe java actionomits the EXTRA CODE block and the hand-added import;- in place,
create or modifykeeps both (verified, step 3) - so this is a round-trip / authoring gap, not data loss.
What narrows it down
| Variant | Result |
|---|---|
create → hand-written EXTRA CODE + import → create or modify with a new body |
EXTRA CODE and the import kept ✅ |
import java.util.Objects; as the first line of the body |
moved to the import list, deduplicated ✅ |
describe after a hand-written EXTRA CODE block |
block and the hand-added import missing ❌ |
| the describe output executed on a fresh project | body calls a missing helper, EXTRA CODE empty ❌ |
Related: #1429 (the same round trip for JavaScript actions, where in-place regeneration also emptied the block -
fixed), #1588 (describe / create parity for parameter descriptions), #1653 (class javadoc).
Suggestions
- Print the EXTRA CODE block in
describeand accept it increate [or modify](an optional second$$block);
omitted = keep what is stored, as today. - Print hand-added imports as
import …;lines at the top of the body - exec already hoists them. - Until then,
describecould warn when the stored file has a non-empty EXTRA CODE block ("not represented in MDL").
Workaround we use
Helpers shared by actions live in a plain class under javasource/<module>/impl/, committed with the project, and
the action bodies call it. A sound pattern anyway - but a helper that belongs to one action cannot stay with it, and
nothing tells a script author that a describe output is incomplete.
Session log (isolated HOME; local path replaced by <repro>)
{"time":"2026-10-25T23:43:52.1593557+03:00","level":"INFO","msg":"session_start","version":"v0.28.0","go":"go1.27.3","os":"windows","arch":"amd64","mode":"mxcli exec","args":["C:\\Tools\\mxcli.exe","exec","<repro>/scripts/ewo_ja1.mdl","-p","Repro.mpr"],"pid":52464,"parent_pid":""}
{"time":"2026-10-25T23:43:52.2027204+03:00","level":"INFO","msg":"connect","mpr_path":"Repro.mpr","mendix_version":"11.14.0","mpr_format":2}
{"time":"2026-10-25T23:43:52.2027204+03:00","level":"INFO","msg":"execute","stmt_type":"ConnectStmt","stmt_summary":"connect local 'Repro.mpr'","duration_ms":1}
{"time":"2026-10-25T23:43:54.4402154+03:00","level":"INFO","msg":"execute","stmt_type":"CreateModuleStmt","stmt_summary":"create module ModJ","duration_ms":125}
{"time":"2026-10-25T23:43:54.4923144+03:00","level":"INFO","msg":"execute","stmt_type":"CreateJavaActionStmt","stmt_summary":"create java action ModJ.JA_Twice","duration_ms":50}
{"time":"2026-10-25T23:43:54.5002785+03:00","level":"INFO","msg":"session_end","commands_executed":3,"errors_count":0,"duration_s":2,"pid":52464}
{"time":"2026-10-25T23:43:55.5904231+03:00","level":"INFO","msg":"session_start","version":"v0.28.0","go":"go1.27.3","os":"windows","arch":"amd64","mode":"mxcli exec","args":["C:\\Tools\\mxcli.exe","exec","<repro>/scripts/ewo_ja2.mdl","-p","Repro.mpr"],"pid":68648,"parent_pid":""}
{"time":"2026-10-25T23:43:55.630626+03:00","level":"INFO","msg":"connect","mpr_path":"Repro.mpr","mendix_version":"11.14.0","mpr_format":2}
{"time":"2026-10-25T23:43:55.6310793+03:00","level":"INFO","msg":"execute","stmt_type":"ConnectStmt","stmt_summary":"connect local 'Repro.mpr'","duration_ms":2}
{"time":"2026-10-25T23:43:56.0023191+03:00","level":"INFO","msg":"execute","stmt_type":"CreateJavaActionStmt","stmt_summary":"create java action ModJ.JA_Twice","duration_ms":22}
{"time":"2026-10-25T23:43:56.003263+03:00","level":"INFO","msg":"session_end","commands_executed":2,"errors_count":0,"duration_s":0,"pid":68648}
{"time":"2026-10-25T23:43:56.705713+03:00","level":"INFO","msg":"session_start","version":"v0.28.0","go":"go1.27.3","os":"windows","arch":"amd64","mode":"batch","args":["C:\\Tools\\mxcli.exe","-p","Repro.mpr","-c","describe java action ModJ.JA_Twice"],"pid":66780,"parent_pid":""}
{"time":"2026-10-25T23:43:56.7482525+03:00","level":"INFO","msg":"connect","mpr_path":"Repro.mpr","mendix_version":"11.14.0","mpr_format":2}
{"time":"2026-10-25T23:43:56.7486169+03:00","level":"INFO","msg":"execute","stmt_type":"ConnectStmt","stmt_summary":"connect local 'Repro.mpr'","duration_ms":1}
{"time":"2026-10-25T23:43:56.7855078+03:00","level":"INFO","msg":"execute","stmt_type":"DescribeStmt","stmt_summary":"describe JAVA ACTION ModJ.JA_Twice","duration_ms":19}
{"time":"2026-10-25T23:43:56.7855078+03:00","level":"INFO","msg":"session_end","commands_executed":2,"errors_count":0,"duration_s":0,"pid":66780}
{"time":"2026-10-25T23:43:57.3434026+03:00","level":"INFO","msg":"session_start","version":"v0.28.0","go":"go1.27.3","os":"windows","arch":"amd64","mode":"batch","args":["C:\\Tools\\mxcli.exe","-p","Repro.mpr","-c","describe java action ModJ.JA_Twice"],"pid":51792,"parent_pid":""}
{"time":"2026-10-25T23:43:57.3838933+03:00","level":"INFO","msg":"connect","mpr_path":"Repro.mpr","mendix_version":"11.14.0","mpr_format":2}
{"time":"2026-10-25T23:43:57.3838933+03:00","level":"INFO","msg":"execute","stmt_type":"ConnectStmt","stmt_summary":"connect local 'Repro.mpr'","duration_ms":2}
{"time":"2026-10-25T23:43:57.4240165+03:00","level":"INFO","msg":"execute","stmt_type":"DescribeStmt","stmt_summary":"describe JAVA ACTION ModJ.JA_Twice","duration_ms":21}
{"time":"2026-10-25T23:43:57.4243252+03:00","level":"INFO","msg":"session_end","commands_executed":2,"errors_count":0,"duration_s":0,"pid":51792}
{"time":"2026-10-25T23:43:58.0071109+03:00","level":"INFO","msg":"session_start","version":"v0.28.0","go":"go1.27.3","os":"windows","arch":"amd64","mode":"mxcli exec","args":["C:\\Tools\\mxcli.exe","exec","<repro>/scripts/ewo_ja3.mdl","-p","Repro.mpr"],"pid":34136,"parent_pid":""}
{"time":"2026-10-25T23:43:58.0471952+03:00","level":"INFO","msg":"connect","mpr_path":"Repro.mpr","mendix_version":"11.14.0","mpr_format":2}
{"time":"2026-10-25T23:43:58.0471952+03:00","level":"INFO","msg":"execute","stmt_type":"ConnectStmt","stmt_summary":"connect local 'Repro.mpr'","duration_ms":2}
{"time":"2026-10-25T23:43:58.4138472+03:00","level":"INFO","msg":"execute","stmt_type":"CreateJavaActionStmt","stmt_summary":"create java action ModJ.JA_Twice","duration_ms":21}
{"time":"2026-10-25T23:43:58.4151842+03:00","level":"INFO","msg":"session_end","commands_executed":2,"errors_count":0,"duration_s":0,"pid":34136}
{"time":"2026-10-25T23:43:59.6544943+03:00","level":"INFO","msg":"session_start","version":"v0.28.0","go":"go1.27.3","os":"windows","arch":"amd64","mode":"mxcli exec","args":["C:\\Tools\\mxcli.exe","exec","<repro>/scripts/ewo_ja0.mdl","-p","Repro.mpr"],"pid":20292,"parent_pid":""}
{"time":"2026-10-25T23:43:59.6964324+03:00","level":"INFO","msg":"connect","mpr_path":"Repro.mpr","mendix_version":"11.14.0","mpr_format":2}
{"time":"2026-10-25T23:43:59.6964324+03:00","level":"INFO","msg":"execute","stmt_type":"ConnectStmt","stmt_summary":"connect local 'Repro.mpr'","duration_ms":1}
{"time":"2026-10-25T23:44:01.895532+03:00","level":"INFO","msg":"execute","stmt_type":"CreateModuleStmt","stmt_summary":"create module ModJ","duration_ms":127}
{"time":"2026-10-25T23:44:01.9003894+03:00","level":"INFO","msg":"session_end","commands_executed":2,"errors_count":0,"duration_s":2,"pid":20292}
{"time":"2026-10-25T23:44:02.5113432+03:00","level":"INFO","msg":"session_start","version":"v0.28.0","go":"go1.27.3","os":"windows","arch":"amd64","mode":"mxcli exec","args":["C:\\Tools\\mxcli.exe","exec","<repro>/scripts/ewo_ja_desc.mdl","-p","Repro.mpr"],"pid":49660,"parent_pid":""}
{"time":"2026-10-25T23:44:02.5516177+03:00","level":"INFO","msg":"connect","mpr_path":"Repro.mpr","mendix_version":"11.14.0","mpr_format":2}
{"time":"2026-10-25T23:44:02.5516177+03:00","level":"INFO","msg":"execute","stmt_type":"ConnectStmt","stmt_summary":"connect local 'Repro.mpr'","duration_ms":1}
{"time":"2026-10-25T23:44:02.9626232+03:00","level":"INFO","msg":"execute","stmt_type":"CreateJavaActionStmt","stmt_summary":"create java action ModJ.JA_Twice","duration_ms":43}
{"time":"2026-10-25T23:44:02.9666825+03:00","level":"INFO","msg":"session_end","commands_executed":2,"errors_count":0,"duration_s":0,"pid":49660}
Activity
Merge pull request mendixlabs#1658 from ako/claude/microflow-activity…
feat: extra code clause for create java action, and describe prints it (