そろそろ年末年始休暇が終わるこの頃、普段使いの道具を OS X Mavericks から macOS High Sierra にアップグレードしたときに出会った Rails と Oracle 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 への接続ができるようになった。