X

The leading edge of scripting languages and Oracle Database brought to you by the Data Access Development team

Avoiding the DPI-1047 error with Node.js node-oracledb 5 on macOS and Windows

Christopher Jones
Senior Principal Product Manager

After installing the Node.js node-oracledb module, beginner users will often see a DPI-1047 error when running their first script. For example on macOS:

$ node example.js
Error: DPI-1047: Cannot locate a 64-bit Oracle Client library: "dlopen(libclntsh.dylib, 1): image not found". See https://oracle.github.io/node-oracledb/INSTALL.html for help
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html

This wouldn't happen if the installation instructions had been followed - but a doc writer can only dream that people actually read manuals!

Downloading Oracle Instant Client

Installing the Oracle Client libraries is easy: they can be freely downloaded from here for macOS and here for Windows 64-bit. Simply download either the latest Basic or Basic Light package and unzip it.

I like to automate things. This is easy on macOS:

cd ~/Downloads
curl -O https://download.oracle.com/otn_software/mac/instantclient/instantclient-basic-macos.zip
unzip instantclient-basic-macos.zip

At time of writing, this will install the Oracle Instant Client 19.3 libraries and create a new directory ~/Downloads/instantclient_19_3.

Telling Node.js where Instant Client is

Now you just need to tell your application where the libraries are. In node-oracledb 5, there are several ways to do this. My favorite is the new oracledb.initOracleClient() function. This is useful on macOS and Windows - particularly with recent macOS changes restricting library access, and changes to how Node.js is compiled. The function can also be used on Linux but there are some limitations - read the manual.

With Instant Client installed on macOS as above, add this to your scripts:

const oracledb = require('oracledb');
if (process.platform === 'darwin') {
  try {
    oracledb.initOracleClient({libDir: process.env.HOME + '/Downloads/instantclient_19_3'});
  } catch (err) {
    console.error('Whoops!');
    console.error(err);
    process.exit(1);
  }
}

On Windows, if you unzipped the Oracle Instant Client Basic package to C:\oracle\instantclient_19_8, then you no longer necessarily need to add this directory to PATH. Instead use:

const oracledb = require('oracledb');
if (process.platform === 'win32') {
  try {
    oracledb.initOracleClient({libDir: 'C:\\oracle\\instantclient_19_8'});   // note the double backslashes
  } catch (err) {
    console.error('Whoops!');
    console.error(err);
    process.exit(1);
  }
}

More

In node-oracledb 5 for macOS we also extended a feature previously usable on Windows to allow Instant Client libraries to be in the same directory as the node-oracledb binary module. Instead of using initOracleClient() macOS users can instead have a package.json script section:

  "scripts": {
    "postinstall": "ln -s $HOME/Downloads/instantclient_19_3/libclntsh.dylib $(npm root)/oracledb/build/Release"
  },

With this, then anytime you install your application on macOS the Oracle Client libraries will be used.

For more information, and other uses of oracledb.initOracleClient(), such as passing the location of optional configuration files like tnsnames.ora, see Initializing Node-oracledb in the node-oracledb documentation.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.