Custom Perl Modules on Apache2 Server - perl

Currently I am trying to use a bunch of custom perl modules, test.pm as one of them, within my Perl program with a WebUI. I am running it on a Windows 7 machine with Apache2 installed. When I run the program in cmd prompt by using perl test.pl, the program runs fine. However running it on Apache gives me this error.
[Wed Jun 13 16:23:32 2012] [error] [client 127.0.0.1] Can't locate test.pm in #INC (#INC contains: C:/Perl/lib C:/Perl/site/lib .) at C:/www/hello2.pl line 7.\r, referer: http://localhost/ui_test.htm
[Wed Jun 13 16:23:32 2012] [error] [client 127.0.0.1] BEGIN failed--compilation aborted at C:/www/hello2.pl line 7.\r, referer: http://localhost/ui_test.htm
I have used:
foreach $key (sort keys(%ENV)) {
print "$key = $ENV{$key}<p> \n";
}
and under the path variable, I do see the folder of where all the modules are located. Is there somewhere else I should use to add to the Perl Path?
In addition adding use lib "C:\testpm\"; to my code only changes the #INC to
(#INC contains: C:\testpm\ C:/Perl/lib C:/Perl/site/lib .)
Is there something additional you need to do to add paths to run custom perl modules on an apache server?
Solution Based On Answer:
I found this to work the best. Within my httpd-perl.conf file, I added these lines:
<IfModule env_module>
SetEnv PERL5LIB "C:\testpm;C:\testpm1;"
</IfModule>
(extended out with C:\testpm1 to show people with similar questions how to add even more module folders.)

The PATH environment variable has no bearing on where perl will load modules from, that is #INC. You said your path is in #INC, but in the error message you show, it is not.
Can't locate test.pm in #INC (#INC contains: C:/Perl/lib C:/Perl/site/lib .) at
You should call use lib during server startup. See http://perl.apache.org/docs/2.0/user/handlers/server.html#Startup_File.
Also, try removing the trailing slash, eg use lib 'C:\testpm'.

use lib is good if you can add in setup file otherwise you will have to add it in every single perl script file.Rather than doing this, you can use PERL5LIB environment variable.
#INC in perl doesn't take value of PATH environment variable rather it can take from PERL5LIB environment variable.
You can add SetEnv PERL5LIB path_to_modules_directory directive in your apache configuration.Your perl script will add this path at front of original #INC value while executing your perl script.

Related

Can I move perl modules without breaking the system?

I have the exact problem described here:
Perl can't find module when run from cron.daily except that my problem applies to a perl script running from crontab.
In my case the error message is:
May 24 22:12:02 trackcam3 test_cron: Can't locate Image/Grab.pm in #INC (you may need to install the Image::Grab module) (#INC contains: /etc/perl /usr/local/lib/arm-linux-gnueabihf/perl/5.24.1 /usr/local/share/perl/5.24.1 /usr/lib/arm-linux-gnueabihf/perl5/5.24 /usr/share/perl5 /usr/lib/arm-linux-gnueabihf/perl/5.24 /usr/share/perl/5.24 /usr/local/lib/site_perl /usr/lib/arm-linux-gnueabihf/perl-base) at /home/darren/upload_image.pl line 33, <DATA> line 1.
May 24 22:12:02 trackcam3 test_cron: BEGIN failed--compilation aborted at /home/darren/upload_image.pl line 33, <DATA> line 1.
The solutions at the link all add something to the path. I would like to know if I can move or copy the modules to somewhere they can be found when perl scripts from crontab.
As part of troubleshooting I have already loaded cron with the same PATH as I have from the terminal but that is not enough to allow the perl module to be found.
The missing module is in ~/perl5/lib/perl5 which is not in #INC
The same perl script call modules that are located at
/usr/lib/arm-linux-gnueabihf/perl5/5.24/Image/Magick
Should it be somewhere else? At present /usr/lib/perl5 is empty. The OP in the link asked the same question in the link but didn't receive an answer.
Try:
use lib glob( '~/perl5/lib/perl5' );
use Image::Grab;
The use lib must come before many use module.
Follow the link in the following comment by #haukex to arrive at a full explanation.

Can't locate XML/XPath.pm in #INC

I have a .pl script in which starts by:
#!/usr/bin/perl
use XML::XPath;
use Getopt::Long;
I can't seem to run that via perl myScript.pl, having this error:
(#INC contains: /usr/share/ /usr/local/lib64/perl5 /usr/local/share/perl5/usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at most_generic_wrapper.pl line 3.
BEGIN failed--compilation aborted at myScript.pl line 3.
1- I tried to locate the XPath.pm file and export that as:
export PERL5LIB=/usr/share/perl5/XML/Twig
and
export PERL5LIB=/usr/share/perl5/XML
2- Installed perl -MCPAN -e 'install XML::Parser'
3- Used -I to explicitly define the path as:
perl -I perl -MCPAN -e 'install XML::Parser' myScript.pl
4- changing the line 3 to use XML::Twig::XPath; led to:
cannot use XML::Twig::XPath: neither XML::XPathEngine 0.09+ nor XML::XPath are available at /usr/share/perl5/XML/Twig/XPath.pm line 11.
BEGIN failed--compilation aborted at /usr/share/perl5/XML/Twig/XPath.pm line 13.`
But none of them solved the issue and I keep receiving the same error at line.3.
P.S: Running on CentOS 6.2 with the kernel 2.6.32-358 and perl --version=v5.10.1 (*) built for x86_64-linux-thread-multi
Any helps would be appreciated,
Your title says XML::XPath can't be found, but your question indicates you tried to install XML::Parser. Did you try to install XML::XPath?
From man perlrun: "If PERL5LIB is not defined, PERLLIB". You seem to have tried setting PERLIB5 (notice the spelling difference: the var is PERL5LIB (or PERLLIB), not PERLIB5).
From man perlrun: "PERL5LIB -- A list of directories in which to look for Perl library files before looking in the standard library and the current directory." You seem to have tried setting it to the full path to a .pm file, rather than a directory.
The file you assigned would be XML::Twig::XPath, not XML::XPath; those are two different Perl modules.
Edit: After looking at your revised question:
I'm not sure if your script requires XML::Twig::XPath or XML::XPath, or if either one can provide the API you need. However, XML::Twig::XPath seems to depend on XML::XPath so you will need XML::XPath no matter what, and it looks like XML::XPath is not installed on your system. I think that's probably the main problem. Please try to install XML::XPath using CPAN.
The value of the PERL5LIB variable (or the argument to the -I option) should be the directory that sits at the base of the package-qualified module file. For example, if XML::XPath is located at ~/perl_custom_modules/XML/XPath.pm, then you need to set PERL5LIB (or the -I argument) to ~/perl_custom_modules. The XML directory is part of the package qualification of the module, so does not need to be included in the include path.

Perl redirects to wrong execution path

I am facing some problem with Perl. During execution, I am getting this error.
Can't locate XML/LibXML/NodeList.pm in #INC (#INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/local/lib64/perl5/XML/LibXML.pm line 25.
But when I tried to find this file using locate command i found it under.
/usr/local/lib/perl5/site_perl/5.18.0/x86_64-linux/XML/LibXML/ directory.
I have installed different perl packages and they are all installed correctly. If I put single file at specified location then it will complain about another file. So putting file manually is not an good idea.
So how do i change its path to so it can execute the files from correct directory?
Edit
Can't locate loadable object for module XML::LibXML in #INC (#INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/local/lib64/perl5/XML/LibXML.pm line 154
[Wed Jul 03 10:15:13 2013] [error] [client 192.73.242.136] BEGIN failed--compilation aborted at /usr/local/lib64/perl5/XML/LibXML.pm line 154.
[Wed Jul 03 10:15:13 2013] [error] [client 192.73.242.136] Compilation failed in require at /var/www/cgi-bin/astpp/astpp-cdr-xml.cgi line 23.
[Wed Jul 03 10:15:13 2013] [error] [client 192.73.242.136] BEGIN failed--compilation aborted at /var/www/cgi-bin/astpp/astpp-cdr-xml.cgi line 23.
[Wed Jul 03 10:15:13 2013] [error] [client 192.73.242.136] Premature end of script headers: astpp-cdr-xml.cgi
The instance of XML::LibXML that you have found probably belongs to a different installation of perl. It may not work even if you extend the search path to include its location.
You should install the library afresh, using whatever tool is appropriate - probably cpan.
I agree with Borodin. It appears that your Perl installation maybe different from the standard Perl already installed on the system.
What happens if you type in:
$ which perl
or
$ type perl
One of these two commands should show you which Perl program is being executed by default.
What Perl executable does the first line of your Perl program point to? (It looks something like #! /usr/bin/perl Are they two different locations?
What happens when you type in perl -V which should list all of the standard locations of where your Perl modules may be installed?
It is also possible that your installation of the XML::LibXML module is bad. I think the directory you see is for the binary program that XML::LibXML depends upon, but there should also be a Perl version that will refer to that binary somewhere like usr/local/lib/perl5/site_perl/5.18.0/XML/LibXML/.
Try reinstalling this module with CPAN and afterwards, run the following command:
$ perldoc -l XML::LibXML::Nodelist
and see where it was installed.

Can't locate File/Glob.pm in #INC (#INC contains: D:/tools/lib .) at directory.pl line 2

I get this error when running my perl code
Can't locate File/Glob.pm in #INC (#INC contains: D:/tools/lib .) at directory.pl line 2.
line 2: #files=<*>;
When i run the command, I get,
Y:\perl\perl>perldoc -l File::Glob
D:\tools\lib\perl\510\File\Glob.pm
So I think the File::Glob module is installed?
#INC should be set correctly upon installation of Perl. When it doesn't match your configuration, you seem to have messed up something.
However, if the current value of #INC doesn't fit your needs, you have various options:
Add D:\tools\lib\perl\510\ to the
environment variable PERL5LIB (or PERLLIB if this doesn't work)
Specify #INC on startup:
perl -I D:\tools\lib\perl\510\
Instead of writing use libname, you can write use path/to/libname
Using a BEGIN block before the use statements:
BEGIN {
push #INC,"D:\tools\lib\perl\510\";
}
See also http://perldoc.perl.org/perlvar.html for a short introduction.

How do I set Perl's #INC for a CGI script?

I have the following, simplest Perl CGI script:
use strict;
use warnings;
use CGI();
use CGI::Carp qw(fatalsToBrowser);
use Template;
print CGI::header();
foreach(#INC) {
print "$_\n";
}
When called (http://[..]/cgi-bin/p.cgi) I am given the following error:
Can't locate Template.pm in #INC (#INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at /home/pistacchio/webapps/htdocs/cgi-bin/p.cgi line 8.
BEGIN failed--compilation aborted at /home/pistacchio/webapps/htdocs/cgi-bin/p.cgi line 8.
I made sure that Template is installed and indeed when running this program from shell it works (loads Template) and outputs:
Content-Type: text/html; charset=ISO-8859-1
/home/pistacchio/lib/perl5
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
/home/pistacchio/lib/perl5/lib
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8
/usr/lib/perl5/site_perl
/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.8
/usr/lib/perl5/vendor_perl
/usr/lib/perl5/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/5.8.8
Template is installed in /home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[pistacchio#web118 i386-linux-thread-multi]$ pwd
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[pistacchio#web118 i386-linux-thread-multi]$ ls
auto perllocal.pod Template Template.pm
This directory is correctly listed in env and, as previously posted, in #INC. In #INC it is shown twice, so I even tried to pop it out before calling use Template, but without result. From env:
[pistacchio#web118 i386-linux-thread-multi]$ env
[..]
PERL5LIB=/home/pistacchio/lib/perl5:/home/pistacchio/lib/perl5/lib:/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[..]
Removing use Template gets rid of the problem.
The webserver doesn't run as your user, so its environment isn't your user environment. You can set that up in a variety of ways depending on your webserver. In Apache, you can use the SetEnv directive:
SetEnv PERL5LIB /path/to/your/libs
That then applies to everything under it. If you have it in a .htaccess file, for instance, it applies to everything under that directory.
If you can't do something like that, you're stuck setting the value of #INC in each script yourself with the lib pragma.
I would suggest adding the following to your CGI
use lib "/home/pistacchio/lib/" ;
The PERL5LIB env variable is presumably not available to CGI programs.
Edit What I meant, any value you have set in PERL5LIB from a shell will not be available.