Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Cygwin fun. Module is loaded, but not being found by the program

Okay a few rules:

  • No, I cannot install Strawberry Perl on this system. I have to use Cygwin.
  • This is Perl 5.8.7. I cannot update it.
  • This is not my system. This is a customer's system, and I cannot modify it to my hearts content.

Now, we've gotten that out of the way...

I have installed Spreadsheet::Read, Spreadsheet::ParseExcel, and Spreadsheet::XLSX on this system. This installed a little Perl script called xlscat. We've done this before on a development box and the UAT box. Now this is the production box.

I am getting the following error:

Parser for XLSX is not installed at /usr/bin/xlscat line 185

I've traced this to Spreadsheet::Read. The relevant code is:

my @parsers = (
    [ csv       => "Text::CSV_XS"               ],
    [ csv       => "Text::CSV_PP"               ], # Version 1.05 and up
    [ csv       => "Text::CSV"                  ], # Version 1.00 and up
    [ ods       => "Spreadsheet::ReadSXC"       ],
    [ sxc       => "Spreadsheet::ReadSXC"       ],
    [ xls       => "Spreadsheet::ParseExcel"    ],
    [ xlsx      => "Spreadsheet::XLSX"          ],
    [ prl       => "Spreadsheet::Perl"          ],

    # Helper modules
    [ ios       => "IO::Scalar"                 ],
    );
my %can = map { $_->[0] => 0 } @parsers;
for (@parsers) {
    my ($flag, $mod) = @$_;
    print STDERR qq(DEBUG: Flag = "$flag" Mod = "$mod"\n);
    $can{$flag} and next;
    eval "require $mod; \$can{\$flag} = '$mod'";
    }
print STDERR Dumper(\%can); #DEBUG:

The lines that start contain the string DEBUG: are mine.

A dump of @parsers shows that everything is loaded correctly. The first debug prints out the value of $flag and $mod correctly.

The problem seems to come from the eval statement. From what I can see, it runs require against a module, and then sets the $can{$flag} variable to $mod if the require succeeds. Apparently, require Spreadsheet::XLSX fails. Here's the relevant output from my debug statements:

DEBUG: Flag = "csv" Mod = "Text::CSV_XS"
DEBUG: Flag = "csv" Mod = "Text::CSV_PP"
DEBUG: Flag = "csv" Mod = "Text::CSV"
DEBUG: Flag = "ods" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "sxc" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "xls" Mod = "Spreadsheet::ParseExcel"
DEBUG: Flag = "xlsx" Mod = "Spreadsheet::XLSX"
DEBUG: Flag = "prl" Mod = "Spreadsheet::Perl"
DEBUG: Flag = "ios" Mod = "IO::Scalar"
$VAR1 = {
      'csv' => 'Text::CSV_XS',
      'sxc' => 0,
      'xlsx' => 0,
      'xls' => 'Spreadsheet::ParseExcel',
      'ios' => 'IO::Scalar',
      'prl' => 0,
      'ods' => 0
    };

Hmmm... Maybe the module isn't installed?

$ perldoc -l Spreadsheet::XLSX
/usr/lib/perl5/site_perl/5.8/Spreadsheet/XLSX.pm

It shows up in perldoc. Let's write a quick test program:

#! /usr/bin/env perl

use Spreadsheet::Read;
use Spreadsheet::XLSX;

print "It works\n";

And...

$ ./test.pl
DEBUG: Flag = "csv" Mod = "Text::CSV_XS"
DEBUG: Flag = "csv" Mod = "Text::CSV_PP"
DEBUG: Flag = "csv" Mod = "Text::CSV"
DEBUG: Flag = "ods" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "sxc" Mod = "Spreadsheet::ReadSXC"
DEBUG: Flag = "xls" Mod = "Spreadsheet::ParseExcel"
DEBUG: Flag = "xlsx" Mod = "Spreadsheet::XLSX"
DEBUG: Flag = "prl" Mod = "Spreadsheet::Perl"
DEBUG: Flag = "ios" Mod = "IO::Scalar"
$VAR1 = {
          'csv' => 'Text::CSV_XS',
          'sxc' => 0,
          'xlsx' => 0,
          'xls' => 'Spreadsheet::ParseExcel',
          'ios' => 'IO::Scalar',
          'prl' => 0,
          'ods' => 0
        };
It works

I can pick up Spreadsheet::XLSX via the use Spreadsheet::XLSX in my test program, yet the require in Spreadsheet::Read doesn't seem to see it.

Why?


Addendum

What do you get if you print Dumper( \%INC ) ? – friedo 2 mins ago

I actually did one better. I added the following line in the loop:

require $mod if ($mod eq "Spreadsheet::XLSX"); #DEBUG

And that produced the error message:

Can't locate Spreadsheet::XLSX in @INC (@INC contains:
    /usr/lib/perl5/5.8/cygwin /usr/lib/perl5/5.8
    /usr/lib/perl5/site_perl/5.8/cygwin
    /usr/lib/perl5/site_perl/5.8
    /usr/lib/perl5/site_perl/5.8/cygwin
    /usr/lib/perl5/site_perl/5.8 
    /usr/lib/perl5/vendor_perl/5.8/cygwin
    /usr/lib/perl5/vendor_perl/5.8 
    /usr/lib/perl5/vendor_perl/5.8/cygwin
    /usr/lib/perl5/vendor_perl/5.8 .) at 
    /usr/lib/perl5/site_perl/5.8/Spreadsheet/Read.pm line 57.
Compilation failed in require at ./test.pl line 3.
BEGIN failed--compilation aborted at ./test.pl line 3.

(NOTE: I reformatted the output, so it wouldn't be 1000+ characters long, and it's easier to see the @INC path).

The module is in /usr/lib/perl5/site_perl/5.8/Spreadsheet/XLSX.pm.

Oh, take a look at this too:

$ pwd
/usr/lib/perl5/site_perl/5.8/Spreadsheet

$ ls -la
total 152
drwxr-xr-x+  4 phalder   Domain Users      0 Nov  1 21:51 .
drwxrwxrw-+ 11 twinborne Users             0 Nov  1 22:28 ..
drwxr-xr-x+  3 phalder   Domain Users      0 Nov  1 20:48 ParseExcel
-rwxr-xr-x   1 phalder   Domain Users 107773 Apr  6  2011 ParseExcel.pm
-rwxrwxrwx   1 phalder   Domain Users  29142 Nov  2 12:53 Read.pm
drwxr-xr-x+  2 phalder   Domain Users      0 Nov  1 21:51 XLSX
-rwxr-xr-x   1 phalder   Domain Users   8411 May 16  2010 XLSX.pm

$ ls -la XLSX
total 48
drwxr-xr-x+ 2 phalder Domain Users     0 Nov  1 21:51 .
drwxr-xr-x+ 4 phalder Domain Users     0 Nov  1 21:51 ..
-rwxr-xr-x  1 phalder Domain Users  5487 May 16  2010 Fmt2007.pm
-rwxr-xr-x  1 phalder Domain Users 37046 May 16  2010 Utility2007.pm

The permissions seem okay.


Another Addendum:

When I did a CPAN reinstall, I got this:

Result: PASS
  /usr/bin/make test -- OK
Running make install
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR: Can't create '/usr/lib/perl5/site_perl/5.8/cygwin/auto/Spreadsheet/Read'
Do not have write permissions on     
'/usr/lib/perl5/site_perl/5.8/cygwin/auto/Spreadsheet/Read'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 at -e line 1
Installing /usr/lib/perl5/site_perl/5.8/Spreadsheet/Read.pm
Installing /usr/share/man/man3/Spreadsheet.Read.3pm
make: *** [pure_site_install] Error 255
   /usr/bin/make install  -- NOT OK

Oops! I didn't check the permission of the /usr/lib/perl5/site_perl/5.8/cygwin directory tree.

Did a chmod -R a+rx * on the whole /usr/lib/perl5 directory. We'll see if it works again.

like image 266
David W. Avatar asked Nov 02 '11 16:11

David W.


1 Answers

Found the Problem

I took a slightly different tact. I modified Spreadsheet::Read to print out $@ after the eval. That way, I could see what error it was getting. Here's the results:

$ ./test.pl
DEBUG: ""DEBUG: "Can't locate Spreadsheet/ReadSXC.pm in @INC
(@INC contains:
    /usr/lib/perl5/5.8/cygwin
    /usr/lib/perl5/5.8
    /usr/lib/perl5/site_perl/5.8/cygwin
    /usr/lib/perl5/site_perl/5.8
    /usr/lib/perl5/site_perl/5.8/cygwin
    /usr/lib/perl5/site_perl/5.8
    /usr/lib/perl5/vendor_perl/5.8/cygwin
    /usr/lib/perl5/vendor_perl/5.8
    /usr/lib/perl5/vendor_perl/5.8/cygwin
    /usr/lib/perl5/vendor_perl/5.8 .) at (eval 8) line 1.
"DEBUG: "Can't locate Spreadsheet/ReadSXC.pm in @INC
(@INC contains: /usr/lib/perl5/5.8/cygwin [...]) at (eval 9) line 1.
"DEBUG: ""DEBUG: "Can't locate Compress/Raw/Zlib.pm in @INC
(@INC contains: /usr/lib/perl5/5.8/cygwin [...]) at (eval 15) line 1.
"DEBUG: "Can't locate Spreadsheet/Perl.pm in @INC
(@INC contains: /usr/lib/perl5/5.8/cygwin [...]) at (eval 18) line 1.

Did you see that? The problem isn't Spreadsheet::XLSX, but Compress::Raw::Zlib. I set the entire permissions on /usr/lib/perl to 777, and then installed Compress::Raw::Zlib and Spreadsheet::ReadSXC.

This must have been a problem when these modules were initially installed. I wasn't the one doing the cpan install, but helping the person over the phone, so I didn't get a chance to see these errors if they popped up. CPAN tends to be really, really noisy, and I've learned to catch the random error message as CPAN runs by.

The problem may have been /usr/lib/perl5/site_perl/5.8/cygwin not having the correct permissions all along.

The program now works.

Thanks for all of your help. Somehow, it lead me down the right trail.

like image 123
David W. Avatar answered Oct 12 '22 01:10

David W.