Introduction
At work, I have to deal with Oracle DB. Specifically I wrote scripts to access the database programmatically and use the dependency Oracle instantclient which provides various bindings to programming languages. How can one install it on Linux? You download the ZIP, it provides various shared object files and its folder must be found in environment variable LD_LIBRARY_PATH
.
Until the latest version 23.5. They broke the build and deliver *.so
files which are not shared object files.
Error message
DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "/opt/oracle-instantclient_23.5/libclntsh.so: file too short
Why is the file too short?
Error reason
As it turns out, files like libclntsh.so
are neither object files nor links to object files. You need to be aware that a common strategy to deliver libFOO.sh
is to create a symlink from libFOO.so
to libFOO.so.VERSION
where VERSION
is the actual shared object file. If you now have a new backwards-compatible release, you can just relink libFOO.so
and libFOO.so.VERSION
to libFOO.so.NEWVERSION
. That way nothing breaks and you don’t have data twice on the storage device.
But in this case, the files are just text files:
$ ldd /opt/oracle-instantclient_23.5/libclntsh.so
not a dynamic executable
$ file /opt/oracle-instantclient_23.5/libclntsh.so
/opt/oracle-instantclient_23.5/libclntsh.so: ASCII text, with no line terminators
It turns out the files are not links (like in previous instantclient releases), but text files naming their desired destination as content. What?!
Fixing the problem
cd /opt/oracle-instantclient_23.5 # go to your instantclient directory
find . -maxdepth 1 -name '*.so*' -size -50c -type f -exec mv '{}' "{}.tmp" \;
for F in ./*.tmp; do ln -s `cat ${F}` ${F%.*} ; rm "$F" ; done
So we append .tmp
to the affected files and then use ln
to actually create the links consumable by linkers.
Conclusion
Oracle provides a broken distribution in 23.5. I wanted to share my workaround with everyone how to get the client running again.