🐛
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_http
gem is required, it then requiresnet/http
.- Then the stdlib version of
net/http
is loaded, since bundler doesn't knownet-http
is a gem dependency, so it doesn't add the gemified version to to the$LOAD_PATH
.- Then the stdlib version of
net/http
requiresnet/protocol
relatively, 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/protocol
is loaded.- Then when
net-imap
is required, it also usesnet-protocol
but this time the gemified version ofnet-protocol
is used, becausenet-imap
properly declares it as a dependency, sobundler
knows 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