Confirmed behavior and scope
On the interpreter backend, a minimal Test::Mojo request aborts while starting Mojo::Server::Daemon because its application accessor returns undef. The exact same program passes on standard Perl and the JVM backend when using the upstream default request timeout. It requires only a local loopback listener, not an external server or fork.
Candidate: d3f9ae5ac31b51810c0d3b83f302438e656a496a (PerlOnJava 5.44.1), PR #1628. Environment: macOS/Darwin arm64, Temurin OpenJDK 24.0.2+12, standard Perl 5.42.2. Distribution: Mojolicious 9.49 (pure Perl). Investigation date: 2026-10-05.
Complete reproducer code
Save this as repro.t:
use strict;
use warnings;
BEGIN { $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll' }
use Mojolicious::Lite;
use Test::Mojo;
use Test::More;
my $t = Test::Mojo->new;
$t->get_ok('/nothing' => {Accept => 'image/png'})->status_is(404);
done_testing;
Do not add an artificially short inactivity timeout. MOJO_REACTOR=Mojo::Reactor::Poll matches the upstream networking tests and avoids an optional reactor dependency.
Recreate the exact module environment
From a PerlOnJava checkout with a built jperl launcher, this recipe downloads the unchanged upstream source. It uses newly created directories, not any investigator's local installation:
export JPERL="$PWD/jperl"
workdir=$(mktemp -d)
curl -fL https://cpan.org/authors/id/S/SR/SRI/Mojolicious-9.49.tar.gz -o "$workdir/Mojolicious-9.49.tar.gz"
shasum -a 256 "$workdir/Mojolicious-9.49.tar.gz"
tar -xzf "$workdir/Mojolicious-9.49.tar.gz" -C "$workdir"
export MOJOLIB="$workdir/Mojolicious-9.49/lib"
# Put the complete inline program above in repro.t.
timeout 60 perl -I"$MOJOLIB" repro.t > perl-result.log 2>&1
timeout 120 "$JPERL" -I"$MOJOLIB" repro.t > jvm-result.log 2>&1
timeout 120 "$JPERL" --interpreter -I"$MOJOLIB" repro.t > interpreter-result.log 2>&1
Archive SHA-256: 281933d4f9b821f669a3e93a466daaad5596443ea2cb167fa7c019752bce6d66.
Allow local socket creation. An OS/sandbox denial such as Can't create listen socket: Operation not permitted is a setup failure and must be resolved before comparing backends. The recorded behavioral comparisons were all made with loopback access permitted. No upstream source or test was changed, no compatibility shim was added, and no optional JSON XS dependency is needed for this request.
Exact results
Standard Perl and JVM, exit 0:
ok 1 - GET /nothing
ok 2 - 404 Not Found
1..2
Interpreter, exit 255, before any assertion completes:
Can't call method "server" on an undefined value at Mojo/Server/Daemon.pm line 55.
Both PerlOnJava runs also print existing experimental signature/@_ warnings from the bundled File/stat.pm at lines 198, 202, and 213. The JVM succeeds despite these warnings, so they do not by themselves explain the interpreter abort.
Earliest known source divergence
The unchanged Daemon start method reaches:
sub start {
my $self = shift;
my $loop = $self->ioloop;
if (my $max = $self->max_clients) { $loop->max_connections($max) }
# ...
elsif (!@{$self->acceptors}) {
$self->app->server($self); # line 55: receiver of server() is undef
$self->_listen($_) for @{$self->listen};
}
return $self;
}
The diagnostic concerns $self->app, not an undefined daemon or a remote HTTP status. Relevant upstream ownership paths:
# Mojo::Server
has app => sub { shift->build_app('Mojo::HelloWorld') };
# Test::Mojo
sub app {
my ($self, $app) = @_;
return $self->ua->server->app unless $app;
$self->ua->server->app($app);
return $self;
}
The failure is backend-specific on this source candidate. It may concern generated accessor arguments, application ownership/lifetime, or interpreter dispatch; those are hypotheses, not established root causes. Capturing the app before startup and comparing explicit versus default app construction are the next discriminating reductions.
Investigation already ruled out
An earlier reduction set inactivity_timeout(5) and caused a JVM client timeout while the first debug 404 page compiled. Trace output showed that the application did render 404 and subsequent cached requests succeeded. A later control with the upstream default timeout passed on JVM. Do not use that shortened-timeout experiment as proof of an HTTP semantics bug or a performance regression on the shared production host.
The full CPAN run 20261004-150842-64297 separately reported failures in t/mojolicious/proxy_app.t and t/mojolicious/restful_lite_app.t on the default/JVM acceptance path. Their causes remain unclassified. This interpreter startup failure has not been shown to explain them, and closing this ticket must not silently clear those qualification gaps.
Related work and duplicate check
Open and closed issues were searched for Test::Mojo and Daemon.pm on 2026-10-05; no matching issue was found. No fork, parser compilation failure, or #1269 behavior appears in the reduced program.
Acceptance criteria and next work
All decisive diagnostics, source excerpts, and reproducer code are embedded here. No investigator-local files are needed.
Confirmed behavior and scope
On the interpreter backend, a minimal Test::Mojo request aborts while starting Mojo::Server::Daemon because its application accessor returns undef. The exact same program passes on standard Perl and the JVM backend when using the upstream default request timeout. It requires only a local loopback listener, not an external server or fork.
Candidate:
d3f9ae5ac31b51810c0d3b83f302438e656a496a(PerlOnJava 5.44.1), PR #1628. Environment: macOS/Darwin arm64, Temurin OpenJDK 24.0.2+12, standard Perl 5.42.2. Distribution: Mojolicious 9.49 (pure Perl). Investigation date: 2026-10-05.Complete reproducer code
Save this as
repro.t:Do not add an artificially short inactivity timeout.
MOJO_REACTOR=Mojo::Reactor::Pollmatches the upstream networking tests and avoids an optional reactor dependency.Recreate the exact module environment
From a PerlOnJava checkout with a built
jperllauncher, this recipe downloads the unchanged upstream source. It uses newly created directories, not any investigator's local installation:Archive SHA-256:
281933d4f9b821f669a3e93a466daaad5596443ea2cb167fa7c019752bce6d66.Allow local socket creation. An OS/sandbox denial such as
Can't create listen socket: Operation not permittedis a setup failure and must be resolved before comparing backends. The recorded behavioral comparisons were all made with loopback access permitted. No upstream source or test was changed, no compatibility shim was added, and no optional JSON XS dependency is needed for this request.Exact results
Standard Perl and JVM, exit 0:
Interpreter, exit 255, before any assertion completes:
Both PerlOnJava runs also print existing experimental signature/@_ warnings from the bundled File/stat.pm at lines 198, 202, and 213. The JVM succeeds despite these warnings, so they do not by themselves explain the interpreter abort.
Earliest known source divergence
The unchanged Daemon start method reaches:
The diagnostic concerns
$self->app, not an undefined daemon or a remote HTTP status. Relevant upstream ownership paths:The failure is backend-specific on this source candidate. It may concern generated accessor arguments, application ownership/lifetime, or interpreter dispatch; those are hypotheses, not established root causes. Capturing the app before startup and comparing explicit versus default app construction are the next discriminating reductions.
Investigation already ruled out
An earlier reduction set
inactivity_timeout(5)and caused a JVM client timeout while the first debug 404 page compiled. Trace output showed that the application did render 404 and subsequent cached requests succeeded. A later control with the upstream default timeout passed on JVM. Do not use that shortened-timeout experiment as proof of an HTTP semantics bug or a performance regression on the shared production host.The full CPAN run
20261004-150842-64297separately reported failures int/mojolicious/proxy_app.tandt/mojolicious/restful_lite_app.ton the default/JVM acceptance path. Their causes remain unclassified. This interpreter startup failure has not been shown to explain them, and closing this ticket must not silently clear those qualification gaps.Related work and duplicate check
Open and closed issues were searched for Test::Mojo and Daemon.pm on 2026-10-05; no matching issue was found. No fork, parser compilation failure, or #1269 behavior appears in the reduced program.
Acceptance criteria and next work
nice -n 19 makegate.All decisive diagnostics, source excerpts, and reproducer code are embedded here. No investigator-local files are needed.