Wednesday, November 28, 2007

NameError: uninitialized constant SOAP::Mapping::EncodedRegistry

Getting this error:

NameError: uninitialized constant SOAP::Mapping::EncodedRegistry

when trying to use a SOAP4R WSDL generated library?

Join the club.

The reason this error occurs within a Ruby on Rails web project is that the SOAP4R rubygem and SOAP (the built in Ruby library) have the same namespace, yet the EncodedRegistry.rb file is located in only one of those namespaces (i.e. directories).

Rails will attempt to look for the EncodedRegistry.rb file within:
/usr/lib/ruby/1.8/soap/mapping

instead of its actual location within the SOAP4R gem installation: Library/Ruby/Gems/1.8/gems/soap4r-1.5.8/lib/soap/mapping

Note that the above directories are on a Mac OS X Leopard install where Ruby is installed by default.

This occurs when you are loading your SOAP4R WSDL generated library, normally named defaultDriver.rb (unless the WSDL document you used for generating your library was a bit more descriptive and it provided you a name other than "default"). The defaultDriver.rb library file will attempt to require defailtMappingRegistry.rb, which in turn tries to create a SOAP::Mapping::EncodedRegistry object, which is where the namespace clash mentioned above occurs.

SOLUTION:

In your Rails project, within /config/environment.rb, between
Rails::Initializer.run do |config|

end

place the following:

gem 'soap4r

When finished your environment.rb file should contain the following (albeit with a lot more comments which are within this block by default.

Rails::Initializer.run do |config|
gem 'soap4r'
end

After completing that, try loading up your soap4r WSDL generated library via the console.
Within your Rails project root directory type the following:
ruby script/console

Hopefully your console will load with the following:
Loading development environment.
>>

Now we need to load your soap4r WSDL generated library. At the console prompt (>>) type:
require 'defaultdriver'

If the gods are smiling upon you, the library will load with a response something like:
>> ["SOAP"]

If you've built your own classes and modules off of the auto-generated SOAP4R WSDL library, then require your module/class file instead of the defaultDriver.rb generated library.

Other resources:
http://groups.google.com/group/soap4r/browse_thread/thread/17175f520bfc520f
http://dev.ctor.org/soap4r/wiki#Howtos