OS X Mavericks から macOS High Sierra にアップグレードしたときの Oracle のエラー対処の覚書

そろそろ年末年始休暇が終わるこの頃、普段使いの道具を OS X Mavericks から macOS High Sierra にアップグレードしたときに出会った RailsOracle 11g の組み合わせでのエラーについて書き記しておく。なお本筋でない OS のアップグレード自体の話は割愛。

まず OS アップグレード後の動作検証で、そもそも bundle install で詰まっていた ruby-oci8 を個別に gem install を試みた。現象としては以下のようなエラーが発生した。

% gem install ruby-oci8
Building native extensions. This could take a while...
ERROR:  Error installing ruby-oci8:
        ERROR: Failed to build gem native extension.

    current directory: /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8
/Users/koic/.rbenv/versions/2.5.0/bin/ruby -r ./siteconf20180106-73765-18a6i1g.rb extconf.rb
checking for load library path...
  DYLD_LIBRARY_PATH is not set.
  DYLD_FALLBACK_LIBRARY_PATH is not set.
  checking OCI_DIR...
    checking /Users/koic/opt/oracle/lib... yes
  checking dependent shared libraries in /Users/koic/opt/oracle/lib/libclntsh.dylib.11.1...
*** 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.


Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/Users/koic/.rbenv/versions/2.5.0/bin/$(RUBY_BASE_NAME)
        --with-instant-client
        --without-instant-client
/Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:494:in `block in check_ic_dir': RuntimeError (RuntimeError)
        from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:484:in `open'
        from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:484:in `check_ic_dir'
        from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:265:in `get'
        from extconf.rb:22:in `<main>'
---------------------------------------------------
Error Message:
  The output of "otool -L /Users/koic/opt/oracle/lib/libclntsh.dylib.11.1" is:
    | /Users/koic/opt/oracle/lib/libclntsh.dylib.11.1:
    |   /ade/b/2649109290/oracle/rdbms/lib/libclntsh.dylib.11.1 (compatibility version 0.0.0, current version 0.0.0)
    |   /ade/b/2649109290/oracle/ldap/lib/libnnz11.dylib (compatibility version 0.0.0, current version 0.0.0)
    |   /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

  Ruby-oci8 doesn't work without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH
  because the dependent file "/ade/b/2649109290/oracle/rdbms/lib/libclntsh.dylib.11.1" doesn't exist.

  If you need to use ruby-oci8 without DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH,
  download "fix_oralib.rb" in https://github.com/kubo/fix_oralib_osx
  and execute it in the directory "/Users/koic/opt/oracle/lib" as follows to fix the path.

    cd /Users/koic/opt/oracle/lib
    curl -O https://raw.githubusercontent.com/kubo/fix_oralib_osx/master/fix_oralib.rb
    ruby fix_oralib.rb

  Note: DYLD_* environment variables are unavailable for security reasons on OS X 10.11 El Capitan.

Backtrace:
  /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:494:in `block in check_ic_dir'
  /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:484:in `open'
  /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:484:in `check_ic_dir'
  /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:265:in `get'
  extconf.rb:22:in `<main>'
---------------------------------------------------
See:
 * http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-full-client.md for Oracle full client
 * http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-instant-client.md for Oracle instant client
 * http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-on-osx.md for OS X
 * http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/report-installation-issue.md to report an issue.


extconf failed, exit code 1

Gem files will remain installed in /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5.1 for inspection.
Results logged to /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-13/2.5.0-static/ruby-oci8-2.2.5.1/gem_make.out

ここはエラーメッセージ中の以下のコマンドを実行したが、環境によっては割愛できるかもしれない。

% cd /Users/koic/opt/oracle/lib
% curl -O https://raw.githubusercontent.com/kubo/fix_oralib_osx/master/fix_oralib.rb
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7477  100  7477    0     0  18359      0 --:--:-- --:--:-- --:--:-- 18371
% ruby fix_oralib.rb
---------------------------------------------------------------------
Caution!

  fix_oralib.rb has been obsolete since Oracle Instant Client 12.1
  for OS X was released.
  See https://github.com/kubo/fix_oralib_osx
---------------------------------------------------------------------

(snip)

ruby fix_oralib.rb までの実行が終わったら再度 gem install ruby-oci8 する。

% gem install ruby-oci8
Fetching: ruby-oci8-2.2.5.1.gem (100%)
Building native extensions. This could take a while...
Successfully installed ruby-oci8-2.2.5.1

ビルド自体は成功したようだが、ここで bin/rails c で動作確認をしてみたところ、以下のようにバイナリがうまく読めていないとのエラーが発生した。

% bin/rails c

(snip)

         5: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `require'
         4: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:258:in `load_dependency'
         3: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `block in require'
         2: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `require'
         1: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activerecord-oracle_enhanced-adapter-1.8.2/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb:3:in `<top (required)>'
/Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activerecord-oracle_enhanced-adapter-1.8.2/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb:7:in `rescue in <top (required)>': ERROR: 'dlopen(/Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5/lib/oci8lib_250.bundle, 9): Library not loaded: /ade/b/2649109290/oracle/rdbms/lib/libclntsh.dylib.11.1 (LoadError)
  Referenced from: /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5/lib/oci8lib_250.bundle
  Reason: image not found - /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5/lib/oci8lib_250.bundle'. ActiveRecord oracle_enhanced adapter could not load ruby-oci8 library. You may need install ruby-oci8 gem.

ruby-oci8 は Native ビルドの Gem なので、何はともあれひとまず bundle pristine を行う。

% bundle pristine ruby-oci8
Installing ruby-oci8 2.2.5 with native extensions

再度 bin/rails c を実行すると ORA-21561 にエラーが変わる。

% bin/rails c

(snip)

         4: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activerecord-oracle_enhanced-adapter-1.8.2/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb:387:in `initialize'
         3: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activerecord-oracle_enhanced-adapter-1.8.2/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb:328:in `new_connection'
         2: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/activerecord-oracle_enhanced-adapter-1.8.2/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb:328:in `new'
         1: from /Users/koic/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ruby-oci8-2.2.5/lib/oci8/oci8.rb:147:in `initialize'
oci8.c:601:in oci8lib_250.bundle: ORA-21561: OID生成に失敗しました (OCIError)

試しに sqlplus でも試みるが期待通り同じエラーが起きる。

% sqlplus user/pass@//yourhost:1521/orcl

SQL*Plus: Release 11.2.0.3.0 Production on 土 1月 6 07:29:22 2018

Copyright (c) 1982, 2012, Oracle.  All rights reserved.

ERROR:
ORA-21561: OID生成に失敗しました

この ORA-21561 で検索するとそれなりにヒットするが、uname -n の結果のホスト名を /etc/hosts の 127.0.0.1 の横に追加することで解決した。これで Oracle への接続ができるようになった。