feat(moose): bundle pure-Perl Moose runtime dependencies#627
Merged
Conversation
Bundle the upstream pure-Perl modules that the bundled Moose 2.4000
needs to load, so `examples/moose.pl` (and any `use Moose;` script)
works on a fresh PerlOnJava install without first running `jcpan` to
populate ~/.perlonjava/lib.
Repro before this change:
JAVA_TOOL_OPTIONS="-Duser.home=/tmp/empty-home" \
./jperl examples/moose.pl
# Can't locate Class/Load.pm in @inc
Modules bundled (copied verbatim from CPAN, all pure-Perl, all under
the same Perl-5 license):
Class/Load.pm
Class/Load/PP.pm
Module/Runtime.pm
Module/Implementation.pm
Data/OptList.pm
Params/Util.pm
Params/Util/PP.pm
Sub/Install.pm
Sub/Exporter.pm
Sub/Exporter/Progressive.pm
MRO/Compat.pm
Devel/OverloadInfo.pm
Devel/StackTrace.pm
Devel/StackTrace/Frame.pm
Dist/CheckConflicts.pm
Eval/Closure.pm
Package/DeprecationManager.pm
Class/Load/XS.pm is intentionally NOT bundled: its only job is to
XSLoader::load() a native .so, which does nothing on the JVM and
leaves Module::Implementation thinking the XS impl loaded
successfully but with no symbols, so callers blow up with
"Undefined subroutine &Class::Load::XS::is_class_loaded". With
Class/Load/XS.pm absent, Module::Implementation falls back cleanly
to Class::Load::PP. The same reasoning is why we don't ship
Package::Stash::XS.
Verification:
JAVA_TOOL_OPTIONS="-Duser.home=/tmp/empty-home" \
./jperl examples/moose.pl
# 1..7
# all 7 subtests pass
make
# BUILD SUCCESSFUL, all unit tests pass
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
examples/moose.pl(and anyuse Moose;script) failed on a fresh PerlOnJava install with:It worked on machines where
jcpanhad already populated~/.perlonjava/lib, but not on a clean install — because the bundled Moose 2.4000 insrc/main/perl/lib/Moose.pmrequiresClass::Load,Module::Runtime,Data::OptList, etc., and none of those were bundled.This PR bundles the missing pure-Perl runtime dependencies into
src/main/perl/lib/, copied verbatim from CPAN (all under the same Perl-5 license as Perl itself):Class/Load.pm,Class/Load/PP.pmModule/Runtime.pm,Module/Implementation.pmData/OptList.pmParams/Util.pm,Params/Util/PP.pmSub/Install.pm,Sub/Exporter.pm,Sub/Exporter/Progressive.pmMRO/Compat.pmDevel/OverloadInfo.pm,Devel/StackTrace.pm,Devel/StackTrace/Frame.pmDist/CheckConflicts.pmEval/Closure.pmPackage/DeprecationManager.pmWhy
Class/Load/XS.pmis intentionally NOT bundledIts only job is to call
XSLoader::load(), which is a no-op on the JVM. If we shipped it in the jar:Class::Load'sModule::Implementationloader triesXSfirst.XSLoader::load("Class::Load::XS")is called.XSLoaderwalks its fallbacks. Eventually it hitsloadJarShimOverrides, which reads the jar copy ofClass/Load/XS.pmand reports success — even though no symbols got installed.Module::Implementationthinks XS loaded fine, copies nothing intoClass::Load, and the next caller blows up withUndefined subroutine &Class::Load::XS::is_class_loaded.By keeping
Class/Load/XS.pmout of the jar,Module::Implementationcleanly falls through toClass::Load::PP. Same reasoning is why we've never bundledPackage::Stash::XS.What if the user later installs
Class::Load::XSviajcpan?Still safe. The chain becomes:
Class/Load/XS.pmloads from~/.perlonjava/lib, callsXSLoader::load("Class::Load::XS").XSLoader::loadwalks its fallbacks: no Java class, no functional@ISA, no::PPin%INC, and no jar shim forClass::Load::XS(since we didn't bundle one)."Can't load loadable object for module Class::Load::XS: no Java XS implementation available".Module::Implementationwraps the require intry { require_module(...) }, catches the die, and falls back toClass::Load::PP.Verified with a faked install:
Test plan
JAVA_TOOL_OPTIONS="-Duser.home=/tmp/empty-home" ./jperl examples/moose.pl # Can't locate Class/Load.pm in @INCexamples/moose.plpass with a clobbereduser.home:JAVA_TOOL_OPTIONS="-Duser.home=/tmp/empty-home" ./jperl examples/moose.pl # 1..7 (all ok)Class::Load::XSis present inPERL5LIB.makesucceeds (full unit-test suite, no regressions).Generated with Devin