mod_perl failing to locate modules under apache

146 Views Asked by At

I am trying to setup mod_perl like is specified here: Modperl setup manual and I am stuck at very beginning, as I don't possess a good understanding of how to configure yet. Using Apache24 with strawberry perl 5.32.1.1, mod_perl for Apache24 and StrawberryPerl 5.32.1.1, precompiled binaries all 64 bit. In fact perl binaries are loading, but failing at runtime when trying to load some .pm. The errors I get are from Perl.

In Apache httpd.conf I add following section

LoadFile "e:/perlpath/perl\bin\perl532.dll"
LoadModule perl_module modules/mod_perl.so
#SetHandler modperl
#PerlOptions +SetupEnv

The following config is for loading the module PrintEnv:

PerlModule Apache::PrintEnv1
<Location /print_env1>
    SetHandler perl-script
    PerlResponseHandler Apache::PrintEnv1
</Location>

I add the sample module PrintEnv1.pm in e:/apache/Apache. The Apache fails to startup with this error log:

[Mon Nov 20 14:14:41.698220 2023] [perl:error] [pid 1148:tid 352]
     Can't locate Apache/PrintEnv1.pm in @INC (you may need to install the Apache::PrintEnv1 module)
 (@INC contains:
 e:/perlpath/perl/site/lib
 e:/perlpath/perl/vendor/lib
 e:/perlpath/perl/lib
 e:/apache) at (eval 2) line 1.\n
[Mon Nov 20 14:14:41.698220 2023] [perl:error] [pid 1148:tid 352]
     Can't load Perl module Apache::PrintEnv1 for server localhost:80, exiting...

When I comment out following line PerlModule Apache::PrintEnv1 in httpd.conf apache starts ok. But when I run http://localhost/print_env1 in browser I get another runtime error, requiring RequestRec.pm

[Mon Nov 20 14:25:17.540560 2023] [perl:error] [pid 25088:tid 1196] [client ::1:62051]
    failed to resolve handler `Apache::PrintEnv1':
    Can't locate Apache/RequestRec.pm
    in @INC (you may need to install the Apache::RequestRec module) 
 (@INC contains:
 e:/perlpath/perl/site/lib
 e:/perlpath/perl/vendor/lib
 e:/perlpath/perl/lib
 e:/apache) at (eval 2) line 1.\n
#PerlModule Apache::PrintEnv1
<Location /print_env1>
    SetHandler perl-script
    PerlResponseHandler Apache::PrintEnv1
</Location>

The RequestReq.pm is located here e:/perlpath/perl\site\lib\Apache2 In the Modperl setup manual the module is specified as Apache/PrintEnv1.pm, and the problem probably is there use Apache::RequestRec ()

package Apache::PrintEnv1;

use strict;
use warnings;

use Apache::RequestRec ( ); # for $r->content_type

use Apache::Const -compile => 'OK';

sub handler {
    my $r = shift;

    $r->content_type('text/plain');
    for (sort keys %ENV){
        print "$_ => $ENV{$_}\n";
    }

    return Apache::OK;
}

1;

There are specified for instance some startup files, but when I add startup file PerlRequire "C:\apache\perl\startup.pl" I get following error [perl:error] [pid 27768:tid 336] Can't locate Apache2.pm in @INC

UPDATE 1:
I found Apache2.ph in these two places

e:/perlpath/perl\site\lib\APR\Request
e:/perlpath/perl\site\lib\Bundle

Files not identical, 627 vs 1868 bytes.

Here is the startup.pl from the Modperl setup manual

use Apache2 ( );

use lib qw(/home/httpd/perl);

# enable if the mod_perl 1.0 compatibility is needed
# use Apache::compat ( );

# preload all mp2 modules
# use ModPerl::MethodLookup;
# ModPerl::MethodLookup::preload_all_modules( );

use ModPerl::Util ( ); #for CORE::GLOBAL::exit

use Apache::RequestRec ( );
use Apache::RequestIO ( );
use Apache::RequestUtil ( );

use Apache::Server ( );
use Apache::ServerUtil ( );
use Apache::Connection ( );
use Apache::Log ( );

use APR::Table ( );

use ModPerl::Registry ( );

use Apache::Const -compile => ':common';
use APR::Const -compile => ':common';

1;
1

There are 1 best solutions below

0
On

While installing mod_perl2 x64 for Apache24 x64 and StrawBerryPerl5.32.1.1, deployed in two main folders, for instance e:\apachepath and e:\perlpath which are the root folders of Apache24 and StrawberryPerl 5.32.1.1. Just to keep environment clean, no install package used, all unpacked from zip archives precompiled binaries.

I felt like is the right thing to post my solution, as too many things written about too little things to do, to make it working. First of all, it is no more mod_perl but it is mod_perl2. And should be used mod_perl2 documentation instead. That's not so obvious for users who never dealt with any versions of mod_perl before.

Faced two different problems, one about using .pm handlers, and the other about loading the startup.pl, naming conventionally Problem1 and Problem2. Note, using startup.pl is not required for Problem1.

Note, there was no more need to care about Can't locate blabla.pm in @INC, all automatically went away without any path additions.

Problem1
Running the .pm handlers. Here are the changes added to httpd.conf

LoadFile "e:\perlpath\perl\bin\perl532.dll"
LoadModule perl_module modules/mod_perl.so

<Location /print_env1>
    SetHandler perl-script
    PerlResponseHandler MyApache2::PrintEnv1
</Location>
<Location /print_env2>
    SetHandler modperl
    PerlResponseHandler MyApache2::PrintEnv2
</Location>

PrintEnv1.pm located in e:\apachepath\MyApache2

package MyApache2::PrintEnv2;

use strict;
use warnings;

use Apache2::RequestRec ( ); # for $r->content_type
use Apache2::Const -compile => ':common';

sub handler {
    my $r = shift;
    $r->content_type('text/plain');
    for (sort keys %ENV) {   print "$_ => $ENV{$_}\n";   }
    return Apache2::Const::OK;
}

1;

PrintEnv2.pm located in e:\apachepath\MyApache2

package MyApache2::PrintEnv2;
use strict;

use Apache2::RequestRec (); # for $r->content_type
use Apache2::RequestIO ();  # for $r->print

use Apache2::Const -compile => ':common';

sub handler
{
    my $r = shift;
    $r->content_type ('text/plain');
    $r->subprocess_env;
    for (sort keys %ENV) {  $r->print("$_ => $ENV{$_}\n");  }
    return Apache2::Const::OK;
}
1;

Problem solved. Now running from the browser http://localhost/print_env1 and http://localhost/print_env2 will execute, no error logged.
If I add PerlModule, is almost the same, but the .pm scripts are parsed on Apache startup. So, Apache will fail to start if anything is wrong with the scripts. There is what is httpd.conf now

LoadFile "e:\perlpath\perl\bin\perl532.dll"
LoadModule perl_module modules/mod_perl.so
PerlModule MyApache2::PrintEnv1
<Location /print_env1>
    SetHandler perl-script
    PerlResponseHandler MyApache2::PrintEnv1
</Location>
PerlModule MyApache2::PrintEnv2
<Location /print_env2>
    SetHandler modperl
    PerlResponseHandler MyApache2::PrintEnv2
</Location>

Problem2
The other problem was about using startup.pl. Here is the httpd.conf

LoadFile "e:\perlpath\perl\bin\perl532.dll"
LoadModule perl_module modules/mod_perl.so
#almost same as same as PerlRequire
PerlPostConfigRequire "e:\apachepath\perl\startup.pl"

Note, above changes have nothing to do with problem1, which can be taken separately or not. Now the startup.pl, should correspond to mod_perl2 instead of mod_perl, and can be taken entirely from here

use lib qw(/home/httpd/perl);

use ModPerl::Util ( ); #for CORE::GLOBAL::exit

use Apache2::RequestRec ( );
use Apache2::RequestIO ( );
use Apache2::RequestUtil ( );

use Apache2::ServerRec ( );
use Apache2::ServerUtil ( );
use Apache2::Connection ( );
use Apache2::Log ( );

use APR::Table ( );

use ModPerl::Registry ( );

use Apache2::Const -compile => ':common';
use APR::Const -compile => ':common';

1;

Particularly info about transition to mod_perl2 also useful.