Skip to content

Fixed: Call to non-existing method in production run PDF reports (OFBIZ-13504) - #1827

Open
toaditi wants to merge 2 commits into
apache:trunkfrom
toaditi:ofbiz-13504-todatestring-visibility
Open

Fixed: Call to non-existing method in production run PDF reports (OFBIZ-13504)#1827
toaditi wants to merge 2 commits into
apache:trunkfrom
toaditi:ofbiz-13504-todatestring-visibility

Conversation

@toaditi

@toaditi toaditi commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Credits

Thanks to Carsten Heinrigs for reporting OFBIZ-13504 and for pinpointing both the
template and the method involved, which made this quick to pick up.

This follows up on the scope-reduction work in OFBIZ-10478 by Jacques Le Roux
and Pradhan Yash Sharma, reviewed by Michael Brohl -- a broad and valuable
cleanup, in which this one method happened to have callers that static analysis
could not see.

The problem

UtilDateTime.toDateString(Date, String) was narrowed from public to private in
commit abb4ead2f6 (OFBIZ-10478). FreeMarker resolves Static["..."] members
reflectively and therefore only sees public methods, so the templates calling the
two-argument overload can no longer resolve it:

Java method "static org.apache.ofbiz.base.util.UtilDateTime.toDateString(Date)"
takes 1 argument, but 2 was given.

The render does not throw -- that message is written into the output stream, so in
an .fo.ftl it lands inside the FO XML.

Why restore the method rather than edit the templates

The report originally suggested dropping the format string. That resolves to the
single-argument overload, which is hardcoded to MM/dd/yyyy, so the reports would
render without error but silently switch from day/month to month/day order.

This was discussed on the Jira issue, and Carsten Heinrigs, who reported it, agreed
that restoring the method is the better route
, adding that he values being able to
specify the date format string.

That flexibility is really the crux of it: with the two-argument form private, a
template that needs a particular format has no clean way to ask for one. Restoring it
keeps the current output, fixes every call site at once, and leaves custom templates in
existing deployments working, since they can call this documented helper too.

Call sites fixed (7, across 3 components)

  • applications/manufacturing/template/jobshopmgt/ProductionRun.fo.ftl (4)
  • applications/manufacturing/template/reports/PRunsProductsAndOrder.fo.ftl:324
  • applications/manufacturing/template/reports/PRunsProductsStacks.fo.ftl:92
  • applications/content/template/lookup/ContentTreeLookupList.ftl:85

Verification

Unit: new regression test in FreeMarkerWorkerTests, watched fail then pass. It uses
9 March deliberately, so dd/MM/yyyy (09/03/2026) and MM/dd/yyyy (03/09/2026)
differ -- the test therefore also fails if the format string is dropped.

./gradlew test checkstyleMain codenarcMain javadoc -- BUILD SUCCESSFUL,
854 tests, 0 failures, 0 errors, 0 skipped.

Runtime: a production run was created through createProductionRun with a start
date of 2026-03-09, then PrintProductionRun fetched over HTTP, with only the
one-word change differing between the two runs.

Worth noting that the broken case does not fail. Both runs return HTTP 200 and a
structurally valid one page application/pdf. The difference is what is printed
in the date fields:

before after
HTTP 200 200
bytes 6668 6276
Estimated Start Date Java method "static ...toDateString(Date)" takes 1 argument, but 2 was given followed by an FTL stack trace 09/03/2026

So the report currently prints Java internals where the schedule dates belong,
while the response itself still looks healthy.

release24.09 carries the same private modifier and the same call sites, so it
likely needs the same change -- happy to raise a backport if that seems right.

…IZ-13504)

Jira: https://issues.apache.org/jira/browse/OFBIZ-13504

Thanks to Carsten Heinrigs for reporting this, and for naming both the template
and the method in the report. That made the call site easy to find and saved a
good deal of searching.

This also follows on from OFBIZ-10478 by Jacques Le Roux and Pradhan Yash Sharma,
reviewed by Michael Brohl. That was a broad and worthwhile cleanup; this one
method simply happened to have all of its callers in templates, where static
analysis could not see them.

### What happens today

`UtilDateTime.toDateString(Date, String)` is reached from templates through
`Static["org.apache.ofbiz.base.util.UtilDateTime"]`. FreeMarker resolves those
members reflectively and so sees public methods only. Commit `abb4ead2f6`
narrowed the two argument overload to private, leaving the templates unable to
resolve it:

    Java method "static org.apache.ofbiz.base.util.UtilDateTime.toDateString(Date)"
    takes 1 argument, but 2 was given.

The render does not throw. That message is written into the output stream, so an
`.fo.ftl` still returns a structurally valid PDF, with the FreeMarker error and
an FTL stack trace printed where the dates belong. A production run traveler
prints Java internals in place of its start and completion dates, and the HTTP
response still looks entirely healthy, which is probably why this went unnoticed.

### Why restore the method rather than edit the templates

The report suggests dropping the format string. That resolves to the single
argument overload, which is hardcoded to `MM/dd/yyyy`, so the reports would
render without error but quietly move from day/month to month/day order.

Restoring the two argument overload keeps the rendered output exactly as it was,
fixes every call site at once, and leaves custom templates in existing
deployments working, since they can call this documented helper too.

### Call sites this covers

Seven, across three components:

- `applications/manufacturing/template/jobshopmgt/ProductionRun.fo.ftl`, four
- `applications/manufacturing/template/reports/PRunsProductsAndOrder.fo.ftl:324`
- `applications/manufacturing/template/reports/PRunsProductsStacks.fo.ftl:92`
- `applications/content/template/lookup/ContentTreeLookupList.ftl:85`

### Verification

The regression test renders the failing expression through `FreeMarkerWorker` and
asserts `09/03/2026`. That date is deliberate: its `dd/MM/yyyy` and `MM/dd/yyyy`
forms differ, so the test also fails if the explicit format is dropped rather
than the method restored. It was watched failing before the change and passing
after.

Full unit suite: 108 classes, 854 tests, 0 failures, 0 errors, 0 skipped.
`checkstyleMain`, `codenarcMain` and `javadoc` all pass.

Checked in a running instance as well. A production run was created through
`createProductionRun` with a start date of 2026-03-09, and `PrintProductionRun`
fetched over HTTP. Before the change the PDF carries the FreeMarker stack trace
in the date fields; after it, a valid one page PDF renders `09/03/2026`.

`release24.09` carries the same modifier and the same call sites, so it likely
needs the same change. I would be glad to raise that separately if it seems right.
@toaditi

toaditi commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Update from the Jira thread, for anyone reviewing this cold.

Carsten Heinrigs, who reported the issue, has confirmed he is happy with restoring the
two-argument method rather than editing the templates
, and added that he values being able
to specify the date format string.

That flexibility is really the crux of the choice here. With the two-argument form private, a
template that needs a particular format has no clean way to ask for one, since the
single-argument overload is fixed to MM/dd/yyyy. So this is less about undoing what
OFBIZ-10478 tidied away, and more about keeping a capability that templates — including
customised ones in existing deployments — depend on.

Jira thread: https://issues.apache.org/jira/browse/OFBIZ-13504

…IZ-13504)

Thanks to Carsten Heinrigs for confirming the approach on the Jira issue, and for
noting that the ability to pass an explicit date format is worth keeping. That is
the part most at risk of being lost again, so this records it in the source.

The method has no callers in Java code; its callers are FreeMarker templates using
Static["org.apache.ofbiz.base.util.UtilDateTime"], which static analysis cannot see.
That is exactly why the scope reduction in OFBIZ-10478 looked safe. Without a note
in the code, the next such pass would reasonably reach the same conclusion and
reintroduce the bug.

The comment also records that the failure mode is quiet, and that the single
argument overload is fixed to MM/dd/yyyy, so dropping the pattern is not a neutral
simplification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant