🐛
Net::ProtocRetryErrorのエラーをなくすためにnet-httpのgemを追加する
前提
- Ruby:2.7.1
- rails:6.0.5
結論から
Gemfileに以下を追加する
gem 'net-http'
問題
rails s時などの立ち上げ時に以下のエラー
app_1 | /usr/local/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError
app_1 | /usr/local/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:68: warning: previous definition of ProtocRetryError was here
app_1 | /usr/local/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE
app_1 | /usr/local/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:214: warning: previous definition of BUFSIZE was here
app_1 | /usr/local/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket
app_1 | /usr/local/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:541: warning: previous definition of Socket was here
問題が生じる理由
ref: https://github.com/ruby/net-imap/issues/16#issuecomment-803086765
- When the
faraday-net_httpgem is required, it then requiresnet/http.- Then the stdlib version of
net/httpis loaded, since bundler doesn't knownet-httpis a gem dependency, so it doesn't add the gemified version to to the$LOAD_PATH.- Then the stdlib version of
net/httprequiresnet/protocolrelatively, since that's what it used to happen before these gems were gemified. See [ruby/net-http@6da598e](https://github.com/ruby/net-http/commit/6da598e928f0cc817b1d17209dfaf7fed4c9dff7). So the stdlib version ofnet/protocolis loaded.- Then when
net-imapis required, it also usesnet-protocolbut this time the gemified version ofnet-protocolis used, becausenet-imapproperly declares it as a dependency, sobundlerknows about it and has put it in the$LOAD_PATH. This is what causes the double load ofnet/protocol.
つまり
faraday-net_httpが要求されると、net/httpが必要になる。
しかし、net-httpがgemの依存関係であることをBundlerが認識していないため、gem化されたバージョンが$LOAD_PATHに追加されず、標準ライブラリのnet/httpがロードされる。
そして、標準ライブラリnet/httpはnet/protocolを必要とするのでnet/protocolがロードされる。
そして、net-imapもまた、net-protocolを必要とする。
なのでnet-protocolが二重で呼ばれるのでエラーとなる。
となると、そもそも標準ライブラリのnet/httpを使わせなければいい。つまり、gem版のnet-httpをインストールすればいい。という感じ。
Discussion