gokuraku has asked for the wisdom of the Perl Monks concerning the following question:

In the setup I have there is a small Perl distro with the specific libraries needed, mostly homemade modules and such, plus libraries like INET and INET6. This is to allow the code to run with default installs of Perl, and pull additional libraries as needed from the distro, this has worked fine in the past. I added Socket6.pm to the distro to support the INET6.pm which I needed to get my server script to make an IPv6 server, when I a perl -c on the program I get:

Can't locate object method "bootstrap" via package "Socket6" (perhaps you forgot to load "Socket6"?) at C:/work/newdummy/../Perl/IO/Socket/Socket6.pm line 289. Compilation failed in require at C:/work/newdummy/../Perl/IO/Socket/INET6.pm line 18. BEGIN failed--compilation aborted at C:/work/newdummy/../Perl/IO/Socket/INET6.pm line 18. Compilation failed in require at dummyserver.pl line 22. BEGIN failed--compilation aborted at dummyserver.pl line 22.

The Paths in this are correct, I haven't hit AutoLoader stuff much in the past, and I have always been able to add pm files to the right locations in our distro and have no issues. This one is weird, and like others in the past I copied the source from CPAN and placed it in the package location in IO/Socket, I can't seem to find more about the error though. I've converted the paths in the modules without success, considered maybe the paths needed to be all the same but only the package IO::Socket::Socket6 path was required, the rest of the module refers only to use Socket6 and the bootstrap Socket6 $VERSION line. The only way I have been able to get past this was to remove the line:

bootstrap Socket6 $VERSION;

from the Socket6.pm file, but doing that generates a loop in:

sub AUTOLOAD { my($constname); ($constname = $AUTOLOAD) =~ s/.*:://; my $val = constant($constname, @_ ? $_[0] : 0); if ($! != 0) { if ($! =~ /Invalid/) { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &AutoLoader::AUTOLOAD; } else { my ($pack,$file,$line) = caller; croak "Your vendor has not defined Socket macro $constname, us +ed"; } } eval "sub $AUTOLOAD { $val }"; goto &$AUTOLOAD; }

on the lines:

my($constname); ($constname = $AUTOLOAD) =~ s/.*:://; my $val = constant($constname, @_ ? $_[0] : 0);

which infinitely loops until it takes all the free memory on the machine.

I can't find anything that's really helpful with this, or why I am getting the error only for this library. Been looking into AutoLoader and from what I can tell everything seems to be correct.

Has anyone hit this and gotten past the error at all?

Thanks

Replies are listed 'Best First'.
Re: can't locate object method bootstrap
by almut (Canon) on Dec 20, 2007 at 19:56 UTC
    ... at C:/work/newdummy/../Perl/IO/Socket/Socket6.pm

    What seems strange is that you have Socket6.pm in the directory .../IO/Socket/. And what's even stranger is that something is in fact pulling it in from there...

    The only circumstance under which I can reproduce your problem can't locate object method "bootstrap" via package "Socket6" is by putting Socket6.pm where you have it, plus adjusting the namespace from package Socket6; to package IO::Socket::Socket6;, and then modifying the use statement use Socket6; in IO::Socket::INET6 to read use IO::Socket::Socket6;. In this case I also do get

    Can't locate object method "bootstrap" via package "Socket6" (perhaps +you forgot to load "Socket6"?) at IO/Socket/Socket6.pm line 279.

    (which is not too surprising, as the package is now "IO::Socket::Socket6"...)

    So... did you do anything like this??

    Normally, the directory layout should be:

    .../Perl/Socket6.pm .../Perl/auto/Socket6/Socket6.so # the XS component of Socket6 (.d +ll on Windows) .../Perl/IO/Socket/INET6.pm

    (where .../Perl is a directory that's in @INC)

      Well I tried to put the Socket6.pm in the same location as INET6.pm, which I added in a similar manner as Socket6.pm, and its having no problems being found. It's the call to Socket6.pm from INET6.pm that is generating the issue.

      Tried your paths and it didn't work, but I don't have the auto directory and the SO file since this is a distro that gets moved around, its not a Perl install on the machine. I actually added this into my own ../Perl/Lib directory with the same package info as my own modules that are found without issue, and it generates the "can't load loadable object for module..." error.

      Not even sure where I can go with this unless I try and install the module locally then move the files to my own distro and see if that works.

        ... but I don't have the auto directory and the SO file

        Ah, I'm beginning to see what the problem is.  Thing is, you do need this shared object file, because Socket6 is an architecture-specific Perl module. And if you need to install it on 30+ machines of varying architectures, you're going to need a separate .so file (or .sl or .dll for that matter) for every different architecture (and Perl version). There's no way around it, however unfortunate that may be.

        There are essentially two types of modules: architecture-independent pure Perl modules, and architecture-dependent ones (often called XS modules, because that's the default method to write Perl extensions (Perl-C bindings)). Only the former ones are portable across architectures. The latter ones comprise a shared object file (compiled machine code) in addition to the regular .pm file (and the shared object may itself depend on other shared objects, depending on what it was linked against). It's DynaLoader's bootstrap method that's pulling the .so file in. If it can't find it, you'll get

        can't load loadable object for module...

        The fact that you did not get this message with your other directory setup, but rather the message can't locate object method "bootstrap"... doesn't mean that you've somehow magically gotten past this problem... Quite the contrary, you're not even as far as that. Once the bootstrap method is found, it will complain about the missing .so file.

Re: can't locate object method bootstrap
by ForgotPasswordAgain (Vicar) on Dec 20, 2007 at 16:34 UTC

    Probably need to put this at the top of the file:

    require DynaLoader; our @ISA = qw(DynaLoader);

    And while you're at it, change to this:

    __PACKAGE__->bootstrap($VERSION);

    instead of the ugly indirect-object notation crap.

Re: can't locate object method bootstrap
by Anonymous Monk on Dec 21, 2007 at 07:37 UTC
      True, but as I said, its because we run a distro that is moved to multiple machines and operating systems. We use a default 5.8 install of Perl, with all additional modules and specially made features added to our local distro. This has never come up as an issue in the past, which was why this error has been perplexing. Even if I could install this on the Windows machine I am testing on, that does not help me with the other 30+ machines of Linux, Solaris, AIX and HPUX variants that this needs to run on.
        You can't just copy Socket6.pm to different architectures, because it requires system-dependent C code to be compiled and installed. This applies to any perl module incorporating XS code.

        You need either a system dependent distro for each OS, or you could possibly get around that by building every XS module for each system once, and compile them into a single bundle making sure that only the right file for the current OS is used. I'm not sure which one is easier.

        The point is you haven't installed Socket6, which requires a c/c++ compiler