LoginSignup
4
4

More than 5 years have passed since last update.

capistrano3とaws-sdk v2を組み合わせるとDefinitionErrorにハマった話

Last updated at Posted at 2015-03-04

コメントより追記
2015/9月現在、aws-sdk (2.1.23)が本文書の問題に対応しているそうです。


capistrano3のスクリプト中でaws-sdk v2を使うと以下のようなエラーが起きてハマったのでメモしておきます。

Aws::Resources::Errors::DefinitionError: unable to define method Aws::EC2::DhcpOptions#delete, method already exists

発生状況

Capfileの末尾にrequire "aws-sdk"を書いて、deploy.rb内でAws::EC2::Resource.newしたら発生。

原因

どうもaws-sdk-resources-2.0.28/lib/aws-sdk-resources/operation_methods.rb:72でdefine_methodしている箇所との食い合わせが悪い様子。deleteメソッドを定義しようとしたらすでに定義されててダメーという感じ。

operation_methods.rb
 68       def safe_define_method(method_name, &block)
 69         if instance_methods.include?(method_name.to_sym)
 70           msg = "unable to define method #{name}##{method_name}, "
 71           msg << "method already exists"
 72           raise Errors::DefinitionError, msg
 73         else
 74           define_method(method_name, &block)
 75         end
 76       end

ancestorsを見てみると、capistrano/setup とか capistrano/deploy をrequireした時点で余計なクラスが挟まっている。このせいで、未定義のはずのメソッドが参照できてしまい、エラーになっている模様。

# 正常に動くケースのancestors
[Aws::EC2::DhcpOptions, Aws::Resources::Resource, Object, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject]

# エラーになるケースのancestors
[Aws::EC2::DhcpOptions, Aws::Resources::Resource, Object, JSON::Ext::Generator::GeneratorMethods::Object, Capistrano::DSL, Capistrano::DSL::Stages, Capistrano::DSL::Paths, Capistrano::DSL::Env, Capistrano::TaskEnhancements, Kernel, BasicObject]

対策

capistrano/*をrequireする前にsafe_define_methodを通してしまえ!という乱暴な方法しか思いつかなかった。とりあえず期待通り動いた感じがするけど、良い対応の仕方ではない・・・。より良いアイデアあれば教えていただけると幸いです。

# aws-sdkを先にrequireしてsafe_define_methodを通してしまうおまじない
require 'aws-sdk'
Aws::EC2::Resource

# Load DSL and set up stages
require 'capistrano/setup'

# Include default deployment tasks
require 'capistrano/deploy'
...
...
4
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4