So I've been playing with some Ruby bindings for the VMWare Virtual Infrastructure SOAP web service.

SOAP is, as many of you may be aware, is absolutely f*cking vile and has largely been replaced by RESTful web services. However, if SOAP's all that you have, then SOAP's all that you have.

First thing to take note of: soap4r does not like Ruby 1.9! If you try to use it on Ruby 1.9, you'll see something like this:

dave-work:ESX-vim25-modules_v0.1 dave$ rvm use ruby-head; ruby -v; ruby example1.rb 10.0.0.1

Using /Users/dave/.rvm/gems/ruby-head

ruby 1.9.3dev (2010-10-08 trunk 29426) [x86_64-darwin10.4.0]

/Users/dave/.rvm/gems/ruby-head/gems/soap4r-1.5.8/lib/xsd/charset.rb:13: warning: variable $KCODE is no longer effective
/Users/dave/.rvm/gems/ruby-head/gems/soap4r-1.5.8/lib/xsd/xmlparser.rb:74:in `<top (required)>': XML processor module not found. (RuntimeError)

So let's switch to Ruby 1.8 -

dave-work:ESX-vim25-modules_v0.1 dave$ rvm use 1.8.7-head; ruby -v; ruby example1.rb 10.0.0.1

Using /Users/dave/.rvm/gems/ruby-1.8.7-head

ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-darwin10.4.0]

./Vim25ClassMappingRegistry.rb:16: uninitialized constant SOAP::Mapping::EncodedRegistry (NameError)

This is because of the SOAP::* namespace being both part of the Ruby core libraries and the soap4r namespace. The inclusions of the relevant parts of soap4r are done throughout the code for the VI bindings, but the namespace isn't adjusted.

To fix this, you can ask RubyGems to do its magic and promote soap4r's namespace above the core libraries.

Edit example1.rb. At the top of the file, add this:

require 'rubygems'
gem 'soap4r'

The first statement is required because we're using Ruby 1.8 and the second promotes the soap4r namespace above the core libraries.

That's it! everything will now work. Enjoy using your SOAP service, and I hope it's not too long before you're able to migrate away to something RESTful!