Log::Fine 0.65 template formatter mishandles dynamic placeholders and caller metadata

Open
#1,377 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
java, perl

Research direction

Start with t/13-formatter-template.t using jperl and jperl --interpreter, then inspect Log::Fine::Formatter::Template->format and its _placeHolders cache. Reduce the custom-placeholder, level, and caller() failures into project-owned regressions, confirming which remain distinct. Done means both backends pass the formatter test while the optional Email::Sender skip remains unchanged.

Written by the indexing model from the issue text.

Description

area:backend area:runtime bug

Summary

Log::Fine v0.65 has formatter compatibility failures under PerlOnJava. The upstream suite passes under system Perl, but the template formatter does not preserve all expected dynamic placeholder and caller-metadata behavior.

This was observed in CPAN random tester run 20260914-160652-26153.

Reproduction

The upstream suite passes under system Perl:

  • 22 test programs
  • 2,347 tests
  • all non-optional tests successful

The focused formatter test can be run with:

jperl t/13-formatter-template.t
jperl --interpreter t/13-formatter-template.t

JVM backend result

The archived PerlOnJava run reports 2 failures out of 70 in t/13-formatter-template.t, tests 50 and 51 (lines 174–175).

Those assertions verify that a custom placeholder callback is evaluated dynamically:

my $counter = 0;
sub countplus { return ++$counter; }

custom_placeholders => { foobar => \\&countplus }

The formatter is expected to invoke the callback on each call and emit the incremented counter value. PerlOnJava does not produce the expected output.

Interpreter backend result

The same test was run directly on the interpreter backend and reproduced the two custom-placeholder failures, plus failures involving:

  • %%LEVEL%% rendering
  • %%PACKAGE%%, %%FILENAME%%, %%SUBROUT%%, and %%LINENO%% caller metadata
  • combined template formatting
  • caller metadata in file-handler output

This indicates that the issue is not limited to a single JVM execution path, although the exact failure surface differs between backends.

Expected behavior

Log::Fine::Formatter::Template->format should:

  • invoke each custom placeholder callback each time formatting occurs;
  • substitute the returned value into the template;
  • map numeric logging levels to their configured names;
  • report the caller package, file, subroutine, and line number according to standard Perl caller() behavior; and
  • preserve those values when formatting messages through a file handler.

Technical evidence and diagnosis

The distribution is pure Perl and has no XS/native prerequisite for the failing formatter tests. System Perl passes the complete suite, while PerlOnJava fails reproducibly on both backends.

The formatter implementation caches the parsed placeholder map in _placeHolders, then invokes each callback from format:

my $holders = $self->{_placeHolders} || $self->_placeHolders($tmpl);
...
my $value = &{ $holders->{$holder} }($skip);

The JVM failure in tests 50–51 suggests a problem with callback invocation, lexical state mutation, or returned-value substitution. The interpreter-only additional failures point to separate or related issues in level translation and caller() frame handling. These should be reduced to minimal project-owned regressions before implementation.

Separate environmental failure

The CPAN run also reports one failure in t/pod-coverage.t because Log::Fine::Handle::Email cannot be loaded without the optional Email::Sender dependency. t/15-handle-email.t correctly skips for the same missing dependency. That failure should not be treated as part of the confirmed formatter bug.

Acceptance criteria

  • t/13-formatter-template.t passes on the JVM backend.
  • The same test passes on the interpreter backend.
  • Add focused project-owned regression coverage for dynamic custom placeholder callbacks.
  • Add focused coverage for the affected level and caller() metadata behavior if those failures remain distinct after reducing the reproducer.
  • Preserve the existing optional skip behavior when Email::Sender is unavailable.
Dominant language
Perl
Stars
64
Forks
6
Avg merge
5h 25m
Merged PRs (30d)
157

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from fglock/PerlOnJava

All issues in fglock/PerlOnJava

Similar issues

More Perl issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.