From 09ecb8bc5a2689ca7a2dc8f6b19e15f8362361c0 Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Thu, 30 Apr 2026 12:02:49 +0200 Subject: [PATCH] fix: unblock `jcpan -t Reply` (PerlIO::utf8_strict stub) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `./jcpan -t Reply` failed because PerlIO::utf8_strict (XS) has no Java implementation. It is pulled in by Mixin::Linewise::Readers, which Config::INI::Reader (and therefore Config::INI::Reader::Ordered, a direct prereq of Reply) requires at compile time. Without it, Config::INI::Reader::Ordered's own test suite and Reply's t/00-compile.t both fail to load most of the Reply tree. Changes: * Add `src/main/perl/lib/PerlIO/utf8_strict.pm` as a load-only stub. * Treat `:utf8_strict` as an alias for `:utf8` in `LayeredIOHandle.addLayer` — the JVM's UTF-8 CharsetDecoder already rejects malformed input, which matches the XS module's "strict" semantics. After this change: * `Config::INI::Reader::Ordered` 0.022 — t/reader-ordered.t passes. * `Reply` 0.42 — 23/24 of t/00-compile.t pass; the only remaining failure is `Reply/Plugin/LexicalPersistence.pm loaded ok`, which requires PadWalker (XS lexical-pad introspection). Stubbing PadWalker is left out of this PR because the module's API cannot be meaningfully emulated without a real Perl-style pad model. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../org/perlonjava/core/Configuration.java | 4 +-- .../runtime/io/LayeredIOHandle.java | 8 +++-- src/main/perl/lib/PerlIO/utf8_strict.pm | 33 +++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/main/perl/lib/PerlIO/utf8_strict.pm diff --git a/src/main/java/org/perlonjava/core/Configuration.java b/src/main/java/org/perlonjava/core/Configuration.java index 3db562a92..2e5417a57 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java +++ b/src/main/java/org/perlonjava/core/Configuration.java @@ -33,7 +33,7 @@ public final class Configuration { * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitId = "cfdf262ba"; + public static final String gitCommitId = "f83cf214c"; /** * Git commit date of the build (ISO format: YYYY-MM-DD). @@ -48,7 +48,7 @@ public final class Configuration { * Parsed by App::perlbrew and other tools via: perl -V | grep "Compiled at" * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String buildTimestamp = "Apr 30 2026 10:41:56"; + public static final String buildTimestamp = "Apr 30 2026 12:00:17"; // Prevent instantiation private Configuration() { diff --git a/src/main/java/org/perlonjava/runtime/io/LayeredIOHandle.java b/src/main/java/org/perlonjava/runtime/io/LayeredIOHandle.java index 11b30810c..bc088c82f 100644 --- a/src/main/java/org/perlonjava/runtime/io/LayeredIOHandle.java +++ b/src/main/java/org/perlonjava/runtime/io/LayeredIOHandle.java @@ -376,8 +376,12 @@ private void addLayer(String layerSpec) { inputPipeline = inputPipeline.andThen(inputTransform); outputPipeline = outputPipeline.andThen(outputTransform); } - case "utf8" -> { - // UTF-8 encoding layer - convenience alias for :encoding(UTF-8) + case "utf8", "utf8_strict" -> { + // UTF-8 encoding layer - convenience alias for :encoding(UTF-8). + // :utf8_strict (from the PerlIO::utf8_strict CPAN module) is treated + // as an alias for :utf8 here: the JVM's UTF-8 CharsetDecoder already + // rejects malformed sequences by default, which matches the "strict" + // semantics the XS module provides. EncodingLayer layer = new EncodingLayer(StandardCharsets.UTF_8, "utf8"); activeLayers.add(layer); Function inputTransform = s -> layer.processInput(s); diff --git a/src/main/perl/lib/PerlIO/utf8_strict.pm b/src/main/perl/lib/PerlIO/utf8_strict.pm new file mode 100644 index 000000000..0a3dd5557 --- /dev/null +++ b/src/main/perl/lib/PerlIO/utf8_strict.pm @@ -0,0 +1,33 @@ +package PerlIO::utf8_strict; + +use strict; +use warnings; + +our $VERSION = '0.010'; + +# In standard Perl, PerlIO::utf8_strict is an XS module that provides +# a :utf8_strict PerlIO layer (a stricter UTF-8 layer that rejects +# malformed sequences). In PerlOnJava, IO layers are handled by the +# Java LayeredIOHandle implementation, which treats :utf8_strict as +# an alias for :utf8 (the JVM's UTF-8 decoder already rejects malformed +# input by default via CharsetDecoder, so the "strict" semantics are +# effectively the default). +# +# This stub lets `use PerlIO::utf8_strict;` succeed so CPAN modules +# whose prerequisite chain lists PerlIO::utf8_strict (e.g. +# Mixin::Linewise -> Config::INI -> Config::INI::Reader::Ordered -> +# Reply) can be loaded. + +1; +__END__ + +=head1 NAME + +PerlIO::utf8_strict - stub module for PerlOnJava + +=head1 DESCRIPTION + +Stub for PerlIO::utf8_strict. The C<:utf8_strict> layer is treated +as an alias for C<:utf8> by PerlOnJava's LayeredIOHandle. + +=cut