Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Causing discord between Net::FTP and IO::Sockets

by Cefu (Beadle)
on Jan 26, 2009 at 21:00 UTC ( [id://739030]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow Monks,

It seems the rumors my code is spreading about Net::FTP are souring it's relationship with IO::Sockets.

I'm receiving the following error at the end of one of my modules:

Can't locate object method "new" via package "Net::FTP::A" at /i/forge +t/exact/path/IO/Socket.pm line 168.

I searched for this problem and found several posts (2 from PerlMonks even) about very similar errors; in each case the answer was a missing or incorrectly installed Net::FTP package. I'm almost certain this is not my issue as I have two very similar programs, one of which gets this error and the other does not (running on the same machine invoking the same version of PERL from the same user account etc. etc.).

Both programs do some electronic polling of devices, collate some data, save it to a file then FTP that file to the reports server. The following code is common to both programs:

#!/usr/local/bin/perl use strict; my $workingdir="/some/directory/electronic_polling_scripts"; . . . ftpFile($workingdir . "/RESULTS/MyBlobOData.csv"); sub ftpFile{ use Net::FTP; print "FTP File to Reports Server\n"; my ($file) = @_; my $ftp; $ftp = Net::FTP->new("reportserver.domain.name"); $ftp->login("anonymous","anonpw"); $ftp->cwd("ePolling/Script1_data"); $ftp->put($file); $ftp->quit; print "FTP Complete\n"; return; }

Not suspecting anything in the code above (remember, the other program works flawlessly) I moved on to the Sockets.pm line listed in the error message. The following code is from the Sockets.pm (version 1.29 if that helps) which my program seems to be invoking. The snippet ends with the problem-child, line 168:

sub_accept { @_ == 1 || @- == 2 or croak 'usage $sock->accept([PKG])'; my $sock = shift; my $pkg = shift || $sock; my $timeout = ${*$sock}{'io_socket_timeout'}; my $new = $pkg->new(Timeout => $timeout);

So it seems that Socket.pm assumes that the Package referenced in $pkg has a 'new' method. I don't know what is passed when sub_accept is called nor do I understand exactly how the code above pulls that into $pkg. I would guess that in the normal course of things $pkg references Net::FTP and the resulting Net::FTP->new() is fine. In my case, however, it seems that $pkg must contain a reference to Net::FTP::A for some reason. I've looked into Net/FTP/A.pm and it indeed does not (nor was it intended to) have a 'new' method.

As I said one program gets the error while the other, differing only in the polling/processing which I skipped above, does not. Following this lead I fed the first program bogus input such that it never did any real processing and found that it could run error-free (successfully FTPing a small file) as well. So it seems that something I do during processing screws up what gets into Socket.pm's $pkg variable and breaks the wonderful, trusting relationship these two packages normally have.

Anyone have an idea what I could be doing to muck things up here?

Thanks,
Cefu

Disclaimer: Please don't nitpick the code above; It was hand-typed. The system I'm coding on is specifically (and strictly) isolated from the internet so cut-and-paste is not an option. If it's not potentially the source of my problem then it's probably a typo and I apologize.
The idioms are also not my own; this is recently "inherited" code. Until I find the source of this problem I didn't want to complicate things by remodeling.

I can't reproduce the processing portion of the script verbatim here. If someone has a guess what I might be doing I can look for it in the processing and post some look-alike code.

Replies are listed 'Best First'.
Re: Causing discord between Net::FTP and IO::Sockets
by zwon (Abbot) on Jan 26, 2009 at 21:45 UTC

    Net::FTP::A is a child of Net::FTP::dataconn and dataconn is a child of IO::Socket::INET and IO::Socket::INET has method new. I actually don't understand why I got these results:

    perl -MNet::FTP::A -e 'print Net::FTP::A->can("new") || "can not", "\n +"' can not
    but
    perl -MNet::FTP::A -MIO::Socket::INET -e 'print Net::FTP::A->can("new" +) || "can not", "\n"' CODE(0x10f3d70)

    Update: it looks like a problem in Net::FTP::dataconn. It contains @ISA = qw(IO::Socket::INET), but there's no require IO::Socket::INET

    Update2: you can add use IO::Socket::INET into your programm to fix the problem

      zwon,

      Thanks for helping me think around this problem. I looked at all the @ISA = statements and require statements and saw exactly what you described.

      Adding use IO::Socket::INET; to my code did not fix the problem but fortunately I had already stumbled across the answer.

      In trying to execute your quick check on my platform I accidentally typed in the following:

      perl -MNet::FTP -MIO::Socket::INET -e 'print Net::FTP::A->can("new") || "can not", "\n"'

      and was surprised to get the answer

      can not

      Notice that I had omitted the ::A in the first -M switch. When I corrected the check to be exactly as you typed it, I got the expected result. Adding use IO::Socket::INET; to the existing code made it just like the mistyped check. That is, using the packages Net::FTP and IO::Socket::INET but not explicitly using Net::FTP::A.

      So, by adding the two lines:

      use Net::FTP::A; use IO::Socket::INET;
      to my code I avoided the runtime error.


      Thanks,
      Cefu

      P.S. I'm still confused as to why something I'm doing during processing could selectively trigger this behavior. Is this a bug that I should report to the Net::FTP author or am I doing something extraordinary to trigger this condition?

        It would be great if you show how to reproduce problem. Then I think it would be clear if it's a bug in Net::FTP or in your code.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://739030]
Approved by Corion
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-26 06:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found