Skip to content

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

Closed

Description

@MohamedElNady

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

  1. ewo_ja1.mdl
create module ModJ;
create java action ModJ.JA_Twice(N: Integer not null) returns Integer
as $$
return N * 2L;
$$;
  1. 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 CODE
  1. ewo_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);
$$;
  1. 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);
$$;
  1. 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.create has no clause for the EXTRA CODE section;
  • describe java action omits the EXTRA CODE block and the hand-added import;
  • in place, create or modify keeps 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

  1. Print the EXTRA CODE block in describe and accept it in create [or modify] (an optional second $$ block);
    omitted = keep what is stored, as today.
  2. Print hand-added imports as import …; lines at the top of the body - exec already hoists them.
  3. Until then, describe could 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

  1. added a commit that references this issue on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions