perlcpanstrawberry-perlwww-mechanize-firefoxpp-perl-par-packager

Perl Par::Packer Can't find module issue


I have a perl program that uses WWW::Mechanize::Firefox on windows 7 32bit with strawberry perl.

It works fine with the command C:\>perl testcase.pl. When I compile it with C:\>pp -o testcase.exe testcase.pl it compiles with no errors.

When I run the testcase.exe it gives me the error:

Failed to connect to , Can't locate object method "setup" via package "MozRepl::Client" at MozRepl.pm line 224

The code I am using for testcase.pl is:

#!perl
use MozRepl;
use WWW::Mechanize::Firefox;
use warnings;
system('start firefox');
sleep(5);
$mech = WWW::Mechanize::Firefox->new;

Also note that a program without WWW::Mechanize::Firefox and MozRepl does work fine. The problem has obviously been narrowed down to PAR::Packer not liking MozRepl, any idea what it might be?


Solution

  • PAR::Packer sometimes has a hard time identifying which modules need to be included in a PAR package in order to fulfill all of the requirements of the program you are trying to package.

    It copes OK if the dependancies are loaded via plain 'use', or 'require' statements where the module to be loaded is a literal string, but it won't have much chance if the module is being loaded dynamically with something like:

    require $myModuleToLoad;
    

    Browsing the source code of MozRepl and related modules shows that they make heavy use of plugins loaded dynamically. I suspect that some of these are not being packaged.

    You can manually specify module(s) to be included in the PAR package by adding -M Module::Name to the pp command line for each of the modules to be added (replacing Module::Name with the actual module name of course).

    The hard part might be identifying which modules to include. One way to do this is to temporarily add something like this to the end of your script:

    END { print "$_ -> $INC{$_}\n" foreach sort keys %INC; }
    

    then run your script normally, not through PAR. It should list all the modules that were loaded. You can compare that with the actual modules present in the PAR package and add the missing ones using the -M option to pp.

    You can see the modules inside your PAR file by opening it with an unzipping tool, such as 7zip. Or in Linux:

    unzip -l {parfile}