1

I am having 2 directories in my Apache webserver.

PerlModule HandlerA
PerlModule HandlerB

<Directory "/var/www/html/testa">
    Options FollowSymLinks
    Order deny,allow
    AllowOverride All

    SetHandler perl-script
    PerlHandler HandlerA
</Directory>

<Directory "/var/www/html/testb">
    Options FollowSymLinks
    Order deny,allow
    AllowOverride All

    SetHandler perl-script
    PerlHandler HandlerB
</Directory>

/testa has HandlerA and /testb has HandlerB.

HandlerA.pm

package HandlerA;

use strict;
use warnings;
use Apache2::Const;
use lib "/etc/apache2/a";
use MyA;
use MyX;

sub handler
{
    my $r = shift;

    my $str = "Handler=A  MyA=" . MyA::foo () . "  MyX=" . MyX::foo ();
    $r->log_error ($str);

    $r->content_type ("text/plain");
    print $str;
    return Apache2::Const::OK;
}
1;

HandlerB.pm

package HandlerB;

use strict;
use warnings;
use Apache2::Const;
use lib "/etc/apache2/b";
use MyB;
use MyX;

sub handler
{
    my $r = shift;

    my $str = "Handler=B  MyB=" . MyB::foo () . "  MyX=" . MyX::foo ();
    $r->log_error ($str);

    $r->content_type ("text/plain");
    print $str;
    return Apache2::Const::OK;
}
1;

In each handler I am using foo of a module. The modules reside in a directory a (for HandlerA) and b (for HandlerB).

a/MyA::foo prints A

b/MyB::foo prints B

a/MyX::foo prints A

b/MyX::foo prints B

Only showing a/MyX.pm

package MyX;

sub foo
{
    return "A";
}
1;

Because MyA and MyB differ by name it is working fine that HandlerA uses the correct foo.

But thats not the case with MyX.

How can I make is possible to use a/MyX.pm in HandlerA and b/MyX.pm in HandlerB? So it should use the module not by name but by its file-location.

Output of Handler A should be

Handler=A MyA=A MyX=A

Output of HandlerB should be

Handler=B MyB=B MyX=B

MyX is not always working as expected and it gets mixed up.

chris01
  • 10,921
  • 9
  • 54
  • 93
  • 3
    `@INC` and package namespaces are global. Once you have loaded MyX from the first module, the second use will be a no-op (other than importing once again from MyX that is already loaded). – Grinnz Dec 18 '19 at 22:42
  • 2
    If you did manage to load the second MyX, you would break the parts of the program that expect the first one, since the package namespace is global. – Grinnz Dec 18 '19 at 22:45
  • I have config-data in a package. Worked fine but now I need to have a 2nd instance of the application at another path within the same server. Any idea how I can rebuild that WITHOUT giving any config-package an own name? – chris01 Dec 18 '19 at 23:03
  • mod_perl is a poor framework for this since it does not have such flexibility, you only get the one perl interpreter built into Apache. With a modern web framework, you could have the two different paths proxy to two separate webapp processes. – Grinnz Dec 18 '19 at 23:58
  • 1
    "_MyX is not always working as expected_" -- this is the critical statement and can you elaborate (with an example)? The thing is, I don't see how that can be: when you say `use lib '/etc/apache2/a'` and then `use MyX` it is going to load `MyX` from `a/` of course (and it would never even look at `b`). So you got what you want, no? So how is that failing? /// The other option: can you make it `package a::MyX;` and load as `use a::MyX` (and same for `b`)? If the packages aren't different enough for this to make sense then it should be one (in a common location) anyway. – zdim Dec 19 '19 at 05:59

1 Answers1

0

As Grinzz pinted out, @INC and package namespaces are global - so the solution is to add a different perl interpreter for each directory.

According to the documentation: https://perl.apache.org/docs/2.0/user/config/config.html#C_Parent_ this should work at least in a Location-Directive.

Georg Mavridis
  • 2,312
  • 1
  • 15
  • 23