Using CPAN Modules with PerlOnJava
May 28, 2026 · View on GitHub
Overview
PerlOnJava includes many common CPAN modules and supports installing additional modules from CPAN. It provides jcpan, a CPAN client that works with PerlOnJava, and a custom ExtUtils::MakeMaker that handles module installation without requiring native compilation tools.
Bundled distroprefs and CPAN patches
Some distributions need environment overrides, skipped phases, or small
unified diffs before make test. PerlOnJava ships distroprefs as YAML under
src/main/perl/lib/PerlOnJava/CpanDistroprefs/ and patch files under
src/main/perl/lib/PerlOnJava/CpanPatches/. When CPAN loads, CPAN::Config
copies them into ~/.perlonjava/cpan/prefs/ and ~/.perlonjava/cpan/patches/
respectively (see _bootstrap_prefs / _bootstrap_patches in
src/main/perl/lib/CPAN/Config.pm). Contributor-facing documentation:
CPAN Distroprefs for PerlOnJava and
dev/design/patch-and-cpan-prefs-layout.md.
Quick Start: Installing Modules with jcpan
The recommended way to install CPAN modules is using jcpan:
# Install a module
jcpan install Try::Tiny
# Install with force (ignore test failures)
jcpan -f install Module::Name
# Run a module's test suite
jcpan -t Module::Name
# Interactive CPAN shell
jcpan
Modules are installed to ~/.perlonjava/lib/, which is automatically included in @INC.
Manual Installation
For modules not on CPAN or when you need more control:
# Download and extract
curl -O https://cpan.metacpan.org/authors/id/X/XX/AUTHOR/Module-Name-1.00.tar.gz
tar xzf Module-Name-1.00.tar.gz
cd Module-Name-1.00
# Install with jperl (no make needed)
jperl Makefile.PL
Module Compatibility
Pure Perl Modules
Pure Perl modules (those with only .pm files) work directly with PerlOnJava. Most CPAN modules fall into this category.
XS Modules
XS modules contain C code that must be compiled to native machine code. Since PerlOnJava compiles to JVM bytecode rather than native code, XS modules require special handling.
When you install an XS module, PerlOnJava's MakeMaker:
- Detects the XS/C files
- Installs the
.pmfiles (but not the XS code) - Prints guidance about what will happen at runtime
At runtime, when the module calls XSLoader::load():
- Java implementation available: If PerlOnJava includes a Java implementation of the XS functions, it loads automatically
- Pure Perl fallback: If no Java implementation exists, XSLoader returns an error that many modules catch to fall back to a pure Perl implementation
- No fallback: If the module has no fallback, it fails to load
Many popular XS modules include their own pure Perl fallbacks that activate automatically. The module's .pm file handles this transparently.
For a complete list of XS modules and their compatibility status, see the XS Compatibility Reference.
Built-in Java Implementations
PerlOnJava includes Java implementations of XS functions for several modules:
| Module | Notes |
|---|---|
| DateTime | Uses java.time APIs with JulianFields.RATA_DIE |
| JSON | Delegates to the bundled pure-Perl JSON::PP for full JSON::XS option parity |
| Digest::MD5 | Java MessageDigest API |
| Digest::SHA | Java MessageDigest API |
| Time::HiRes | Java System.nanoTime() |
| DBI | JDBC backend |
| Compress::Zlib | Java zip libraries |
When these modules are loaded, the Java implementation is used automatically for best performance.
Checking Module Availability
# Check if a module is available
./jperl -e 'use Module::Name; print "Available\n"'
# Check if a module uses XS
./jperl -e 'use Module::Name; print Module::Name->can("is_xs") ? "XS" : "PP"'
Available Built-in Modules
PerlOnJava includes 150+ modules without installation. The highlights are listed below; for the complete list see Bundled Modules Reference.
Core Modules
strict,warnings,utf8,featureCarp,Config,Cwd,ExporterFile::Spec,File::Basename,File::Copy,File::Find,File::Path,File::TempIO::File,IO::Handle,FileHandle,DirHandleGetopt::Long,Getopt::StdSys::Hostname,Symbol
Process Control
IPC::Open2,IPC::Open3
Build Tools
ExtUtils::MakeMaker(PerlOnJava version)
Data Processing
JSON- JSON encoding/decodingYAML- YAML parsingTOML- TOML parsingText::CSV- CSV parsingData::Dumper- Data structure dumpingStorable- Data serialization
Cryptography & Encoding
Digest::MD5,Digest::SHAMIME::Base64,MIME::QuotedPrintEncode
Network & Web
HTTP::TinySocketIO::Socket::INET,IO::Socket::UNIXNet::FTP,Net::SMTP,Net::POP3,Net::NNTP
Archives
Archive::Tar,Archive::ZipCompress::Zlib,IO::Zlib
Database
DBI(with JDBC backend)
Testing
Test::More,Test::Simple,Test::Builder
Time
Time::HiRes,Time::PiecePOSIX(including strftime)
Alternative Installation Methods
Local lib Directory
mkdir -p myproject/lib
cp -r Module-Name/lib/* myproject/lib/
./jperl -Imyproject/lib myscript.pl
PERL5LIB Environment Variable
export PERL5LIB=/path/to/your/modules
./jperl myscript.pl
Custom Install Location
PERLONJAVA_LIB=/path/to/libs jperl Makefile.PL
Finding Pure Perl Alternatives
When an XS module doesn't work and has no fallback:
- Visit https://metacpan.org/pod/Module::Name
- Check the source files - if there are
.xsor.cfiles, it's XS - Search for pure Perl alternatives (often named
Module::Name::PPorModule::Name::Pure)
Common substitutions:
| XS Module | Pure Perl Alternative |
|---|---|
| JSON::XS | JSON (built-in) or JSON::PP |
| List::Util (XS parts) | List::Util::PP |
| Params::Util | Params::Util::PP |
Working with Archives
Zip Files
use Archive::Zip qw(:ERROR_CODES);
# Read
my $zip = Archive::Zip->new();
$zip->read('archive.zip') == AZ_OK or die;
print $_->fileName, "\n" for $zip->members();
# Create
my $zip = Archive::Zip->new();
$zip->addFile('document.txt');
$zip->writeToFileNamed('output.zip');
Tar Files
use Archive::Tar;
# Read
my $tar = Archive::Tar->new('archive.tar.gz');
$tar->extract();
# Create
my $tar = Archive::Tar->new();
$tar->add_files('file1.txt', 'file2.txt');
$tar->write('output.tar.gz', COMPRESS_GZIP);
HTTP Requests
use HTTP::Tiny;
my $http = HTTP::Tiny->new();
my $response = $http->get('https://api.example.com/data');
if ($response->{success}) {
print $response->{content};
}
Troubleshooting
"Can't locate Module.pm in @INC"
The module is not installed:
- Install it:
jcpan install Module::Name - Or add it to your lib path:
./jperl -I/path/to/lib script.pl
"Can't load loadable object for module X"
This indicates an XS module without a Java implementation or pure Perl fallback. Options:
- Check if PerlOnJava has a built-in alternative (see table above)
- Look for a pure Perl alternative on CPAN
- Request a Java implementation via GitHub issues
Module loads but functions don't work
Some modules may partially work:
- Check if specific functions require XS (look for
XSLoader::loadin the source) - Some Perl built-ins may not be fully implemented - check the feature matrix
Installation succeeds but module fails at runtime
For XS modules, installation only copies .pm files. The XS functions aren't available unless:
- PerlOnJava has a Java implementation
- The module has a pure Perl fallback
Check the module's documentation for fallback behavior.
See Also
make test-cpan-distroprefs— Full smoke:jcpan -tfor every bundled distropref (slow; logs underbuild/reports/). See patch-and-cpan-prefs-layout.md.- CPAN Distroprefs for PerlOnJava — When and how to add bundled CPAN phase overrides and patches
- Patch and CPAN prefs layout — Where distroprefs and CPAN tarball patches are maintained
- Bundled Modules Reference - Complete list of included modules
- XS Compatibility Reference - Detailed XS module compatibility
- Module Porting Guide - How to port modules to PerlOnJava
- Feature Matrix - Perl feature compatibility
Getting Help
- PerlOnJava Repository: https://github.com/fglock/PerlOnJava
- Issues: Report missing modules or compatibility problems