ray_apps_blog

September 6, 2009

How to setup Ruby and Oracle Instant Client on Snow Leopard

Filed under: mac,oracle,ruby — Raimonds Simanovskis @ 10:57 am

Introduction

Mac OS X Snow Leopard is out and many Rubyists are rushing to upgrade to it. The main difference for Ruby after upgrading to Snow Leopard is that Ruby installation has been changed from 32-bit to 64-bit program and version has changed from 1.8.6 to 1.8.7. And it means that all Ruby gems with C extensions should be reinstalled and recompiled using 64-bit external libraries.

After upgrading to Snow Leopard the first thing to do is to follow instructions on official Ruby on Rails blog. After that follow instructions below.

Installing 64-bit Oracle Instant Client for Intel Mac

Download Oracle Instant Client 64-bit version. Download “Instant Client Package – Basic”, “Instant Client Package – SDK” and “Instant Client Package – SQL*Plus”.

Unzip downloaded archives and move it where you would like to have it – I am keeping it in /usr/local/oracle/instantclient_10_2 (if you have previous 32-bit Oracle Instant Client in this directory then delete it beforehand). Then go to this directory and make symbolic links for dynamic libraries

sudo ln -s libclntsh.dylib.10.1 libclntsh.dylib
sudo ln -s libocci.dylib.10.1 libocci.dylib

Then I recommend to create and place somewhere your tnsnames.ora file where you will keep your database connections definitions – I place this file in directory /usr/local/oracle/network/admin.

Then finally you need to set up necessary environment variables – I place the following definitions in my .bash_profile script:

export DYLD_LIBRARY_PATH="/usr/local/oracle/instantclient_10_2"
export SQLPATH="/usr/local/oracle/instantclient_10_2"
export TNS_ADMIN="/usr/local/oracle/network/admin"
export NLS_LANG="AMERICAN_AMERICA.UTF8"
export PATH=$PATH:$DYLD_LIBRARY_PATH

Use your path to Oracle Instant Client if it differs from /usr/local/oracle/instantclient_10_2. And as you see I also define NLS_LANG environment variable – this is necessary if your database is not in UTF8 encoding but in Ruby you want to get UTF-8 encoded strings from the database. Specifying this NLS_LANG environment variable you will force that Oracle Instant Client will do character set translation.

After these steps relaunch Terminal application (so that new environment variables are set), specify database connection in tnsnames.ora file and try if you can access your database with sqlplus from command line.

Install ruby-oci8 gem

The latest versions of ruby-oci8 are available as Ruby gems and therefore I recommend to install it as a gem and not to compile and install as library (as I have recommended previously in my blog).

If you previously installed ruby-oci8 as a library then I recommend to delete it from Ruby installation. Go to /usr/lib/ruby/site_ruby/1.8 directory and remove oci8.rb file as well as remove oci8lib.bundle compiled library from either universal-darwin9.0 or universal-darwin10.0 subdirectory.

Now install ruby-oci8 with the following command:

sudo env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH ARCHFLAGS="-arch x86_64" gem install ruby-oci8

It is important to pass DYLD_LIBRARY_PATH environment variable to sudo (as otherwise ruby-oci8 gem installation will not find Oracle Instant Client) as well as specify ARCHFLAGS to compile C extension just for 64-bit platform as otherwise it will try to compile both for 32-bit and 64-bit platform.

Now try

ruby -rubygems -e "require 'oci8'; OCI8.new('scott','tiger','orcl').exec('select * from dual') do |r| puts r.join(','); end"

or similar (replacing username, password or database alias) to verify that you can access Oracle database from ruby.

That’s it! Please write in comments if something is not working according to these instructions.

Advertisements

29 Comments

  1. When I installed the Oracle Instant Client, it contained the following files: libclntsh.dylib.10.1 and libocci.dylib.10.1. This worked just fine for my adventures in JDBC. However, when I went to install oci8 for Ruby, I got an error that I should create a symbolic link to these files, removing the “.10.1” from the end of the name. I did that but still could not install. I kept getting this:

    ld: warning: in /Users/gmeazell/Library/instantclient_10_2//libclntsh.dylib, file is not of required architecture

    On a whim, I decided to replace the symbolic links with actual copies of the file and my errors went away.

    Comment by Gerald Meazell — October 9, 2009 @ 8:12 pm

  2. Fantastic article. Thanks for saving my bacon!

    Comment by Sean — November 25, 2009 @ 9:49 am

  3. This all works through the test of oci8, but activerecord-oracle_enhanced-adapter fails to load on my snow leopard MBP. I get the following error:

    irb(main):010:0> require ‘activerecord-oracle_enhanced-adapter’
    MissingSourceFile: no such file to load — activerecord-oracle_enhanced-adapter
    from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’
    from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
    from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:156:in `require’
    from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:521:in `new_constants_in’
    from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:156:in `require’
    from (irb):10
    from :0

    But the enhanced adapter is in fact there:

    irb(main):008:0> gem ‘activerecord-oracle_enhanced-adapter’
    => true

    Any ideas re: how to trouble shoot this?

    Comment by Nick — December 13, 2009 @ 12:44 am

    • If you want to try out oracle_enhanced adapter from irb then you need to load necessary gems and require correct files with correct path:

      require “rubygems”
      gem ‘activerecord’
      gem ‘activerecord-oracle_enhanced-adapter’
      require ‘active_record’
      require ‘active_record/connection_adapters/oracle_enhanced_adapter’

      Comment by Raimonds Simanovskis — December 14, 2009 @ 4:48 pm

  4. Have tried this several times. I keep getting an error …oracle_adapter.rb:575:NameError: undefined method ‘define_a_column’ for class ‘OCI8::Cursor’ when I try to launch a console or server. Any ideas? I’ve triple checked that the $DYLD_LIBRARY_PATH env variable is set correctly and pass it as described in the article.

    Comment by Matt Crawford — December 23, 2009 @ 6:07 pm

    • Can you connect to server using ruby-oci8? (See last paragraph)

      And which ruby-oci8 version do you have? Try from irb:
      require “rubygems”
      require “oci8”
      OCI8::VERSION

      Comment by Raimonds Simanovskis — December 25, 2009 @ 1:04 pm

  5. Ray, this is a great post! Thanks so much for sharing!!

    I also had the same issue with the error “undefined method `define_a_column’ for class `OCI8::Cursor’ (NameError)” in OS X 10.6 (Snow Leopard) and then read a comment by Brendan Boesen ( http://www.ruby-forum.com/topic/182145 ) who stated that the interface changed in ruby-oci8 2.0.0, so you should try using ruby-oci8 1.x.x instead you get that error.

    Basically, you alter Ray’s command above to install v1.x.x, so if you do the following, you should be good:
    sudo gem uninstall ruby-oci8
    sudo env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH ARCHFLAGS=”-arch x86_64″ gem install ruby-oci8 –version “< 2.0.0"

    I also posted the solution here:
    http://stufftohelpyouout.blogspot.com/2010/01/fix-for-undefined-method-defineacolumn.html

    Comment by Gary S. Weaver — January 5, 2010 @ 8:14 pm

  6. Worked great…. thanks

    Comment by John Rice — February 10, 2010 @ 12:33 am

  7. Raimonds Simanovskis, thanks so much for posting this very helpful guide.

    And Gary S. Weaver, thank YOU so very much for posting the little fix. I was stuck there!

    It’s a pleasure to be back up and running with Snow Leopard and Rails/Oracle.

    Comment by Michael Teter — February 17, 2010 @ 6:11 am

    • Actually I recommend to use ruby-oci8 version 2.0.3 and I will support just this version or later in next versions of oracle_enhanced adapter and ruby-plsql gem. What was your issue why ruby-oci8 2.0.3 was not working?

      Comment by Raimonds Simanovskis — February 17, 2010 @ 7:50 pm

  8. Thanks you so very much for your clear and thorough documentation. I had performed the Leopard install and needed to re-install under Snow Leopard, your instructions made this a breeze!

    Comment by Martin Leon — February 17, 2010 @ 11:12 pm

  9. Hi Raimonds,I have done everything in order, but after start sqlplus:

    dyld: Library not loaded: /b/32_216/rdbms/lib/libclntsh.dylib.10.1
    Referenced from: /usr/local/oracle/instantclient_10_2/sqlplus
    Reason: no suitable image found. Did find:
    /usr/local/oracle/instantclient_10_2/libclntsh.dylib.10.1: mach-o, but wrong architecture
    Trace/BPT trap

    what is my mistake?

    Comment by George Ch — February 27, 2010 @ 1:04 pm

    • It complains that dynamic library is not matching sqlplus architecture (most probably one is 32-bit and other is 64-bit or vice versa). Please try to remove all existing Oracle Instant Client files and then reinstall 64-bit Oracle Instant Client (if you are on Snow Leopard) and verify that DYLD_LIBRARY_PATH and PATH environment variables point to correct location of Oracle Instant Client.

      Comment by Raimonds Simanovskis — February 28, 2010 @ 10:13 am

  10. upss.. I downloaded the 32-bit zip files sdk and sqlplus…
    ..now it’s work.. senx ))

    Comment by George Ch — February 28, 2010 @ 3:01 pm

  11. Great article, I, however got stuck on the following command / step:

    sudo env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH ARCHFLAGS=”-arch x86_64″ gem install ruby-oci8

    I get the following error:
    —————————————————
    Building native extensions. This could take a while…
    ERROR: Error installing ruby-oci8:
    ERROR: Failed to build gem native extension.

    /usr/local/bin/ruby extconf.rb
    checking for load library path…
    DYLD_LIBRARY_PATH…
    checking /usr/local/oracle/instantclient_10_2… skip: /usr/local/oracle/instantclient_10_2/libclntsh.dylib.10.1 is for x86_64 cpu.
    checking for cc… ok
    checking for gcc… yes
    checking for LP64… yes
    checking for ruby header… ok
    *** extconf.rb failed ***
    Could not create Makefile due to some reason, probably lack of
    necessary libraries and/or headers. Check the mkmf.log file for more
    details. You may need configuration options.

    along with a list of options available and talking about ORACLE_HOME and client libraries.

    Backtrace:
    ./oraconf.rb:895:in `get_home’
    ./oraconf.rb:682:in `initialize’
    ./oraconf.rb:345:in `new’
    ./oraconf.rb:345:in `get’
    extconf.rb:18
    —————————————————

    Thanks for you help!

    Comment by Matt Simpson — March 5, 2010 @ 1:11 am

    • As I see /usr/local/bin/ruby in error message then I suspect that you are not using original Ruby installation of Snow Leopard but you have installed it separately in /usr/local. And therefore I suspect that it is compiled as 32-bit binary and not 64-bit binary and therefore it is complaining that Oracle library is 64-bit and it cannot use it.

      So either use original Ruby installation of Snow Leopard or recompile Ruby installation in /usr/local as 64-bit binary.

      Comment by Raimonds Simanovskis — March 5, 2010 @ 9:52 am

  12. For a Black Macbook and the first Intel based Mac Mini, you need to do exactly what Raimonds says above and (turns out they’re 32 bit):
    $ set RC_ARCHS=i386
    $ export RC_ARCHS
    $ sudo env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH gem install ruby-oci8

    Very happy with the enhanced adapter. Thanks Raimonds!

    Comment by ACC — March 14, 2010 @ 3:41 pm

  13. Oh My,
    i kept getting the error
    checking for OCIInitialize() in oci.h… no

    So after renegading through the internet and my log files, it kept saying libclntsh.dylib
    is not to the required architecture. So that’s when i checked out the file type and it was a data file( symlink) hmmm.

    when i deleted it and did a copy and paste of libclntsh.dylib
    .10.2 to libclntsh.dylib

    Voila!!! it worked.

    Party over here!!!

    Comment by Kariuki Gathitu — March 31, 2010 @ 11:44 am

  14. For me to work, I had to add the ORACLE_HOME into the command line. Someway this environment variable was getting wiped out and/or ignored.

    sudo env ORACLE_HOME=$ORACLE_HOME DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH ARCHFLAGS=”-arch x86_64″ gem install ruby-oci8

    Comment by Eric — May 6, 2010 @ 11:37 pm

  15. I love the layout

    Comment by Robby Riessen — May 25, 2010 @ 1:09 pm

  16. Hi,

    I followed the instruction above, copying everything in the same folder as the author, but I am getting this error:

    oci8.c:248:in oci8lib.bundle: ORA-12545: Connect failed because target host or object does not exist (OCIError)
    from -e:1:in `new’
    from -e:1

    As far as I know, the name I supplied in the TSNAME file are correct since it is a cut&paste from another machine (a PC) for which everything is working. I have installed both 2.0.3 and 2.0.7 ruby-oci8 gems.

    Running a brand new 13″ MacBook Pro

    Comment by Alain — June 17, 2010 @ 2:22 pm

    • @Alain, We had the same problem copying over from a PC. We ended up retyping in the tnsnames.ora file. We could have probably run it through a filter but it was a short file and easier to retype. Also, on Leopard, we needed to use an upper case TNSNAMES.ora. The good news is that you have connectivity through the stack!

      Comment by ACC — June 17, 2010 @ 4:17 pm

  17. Hello, I found this post via google. Great post and materials.

    Comment by szczyrk — June 23, 2010 @ 12:35 pm

  18. Thanks, was having problems and it was because I was missing the second symlink. Works now, thanks!

    Comment by send9 — July 2, 2010 @ 9:34 pm

  19. Hi,

    I’ve followed the instructions but when I try to run

    sudo env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH ARCHFLAGS=”-arch x86_64″ gem install ruby-oci8

    I get

    —————————————————
    Error Message:
    Set the environment variable ORACLE_HOME if Oracle Full Client.
    Append the path of Oracle client libraries to DYLD_LIBRARY_PATH if Oracle Instant Client.

    DYLD_LIBRARY_PATH is set to “/usr/local/oracle/instantclient_10_2” and the instand client is at /usr/local/oracle/instantclient_10_2

    Has anyone experienced this issue?

    Thanks

    Comment by Austin — July 20, 2010 @ 3:45 pm

  20. Ok- school boy error- when i saw the log also had:

    checking for load library path…
    DYLD_LIBRARY_PATH…
    checking /usr/local/oracle/instantclient_10_2… skip: /usr/local/oracle/instantclient_10_2/libclntsh.dylib.10.1 is for i386 cpu.

    I realised I had downloaded the 32 bit version not the 64 bit.

    Bit of a mistake there ;)

    Comment by Austin — July 20, 2010 @ 4:46 pm

  21. Sweet site, I hadn’t noticed blog.rayapps.com before in my searches! Keep up the great work!

    Comment by rosetta stone language — July 23, 2010 @ 8:38 pm

  22. Thanks – this entry helped sort my more general ‘getting the Pro*C compiler to work’ problem with OS X (main problem – I already had 32-bit instantclient installed prior to Snow Leopard upgrade, so linked problems – but prior to that it was trying to link to an (empty) .so under the main /oracle install.

    The key was installing the instantclient SDK and getting that in the link path, and then setting the arch flags – I don’t think you can get ‘proc’ working using just the Database and Database companion CD alone (no demo make file, no libclntsh.dylib).

    I wonder if that would be worth a blog entry in itself?

    Comment by JulesLt — July 28, 2010 @ 2:41 am

  23. Sweet site, I hadn’t noticed blog.rayapps.com before in my searches! Keep up the great work!

    Comment by แปลเอกสาร — August 6, 2010 @ 10:35 pm


RSS feed for comments on this post.

Blog at WordPress.com.

%d bloggers like this: