0

I have an executable and a .so file which use different versions of the Oracle Instant Client libraries. They are compatible with different versions and I have to use both.

The executable is using version 11 - it is linked to a .so file which is using "libclntsh.so.11.1" -- the version is hard coded and I can't modify the .so file.

ldd Executable_name
    linux-vdso.so.1 =>  (0x00007ffffe7fe000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbb33e80000)
    libdx_t.so => not found
    libudr_t.so => not found
    libnsl.so.1 => /lib64/libnsl.so.1 (0x00007fbb33c66000)
    **libclntsh.so.11.1** => not found
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fbb3395e000)
    libm.so.6 => /lib64/libm.so.6 (0x00007fbb3365c000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fbb33445000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fbb33084000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fbb340aa000)

The .so file is using version 12 and it is using dlopen.

ldd libOracleClient.so
    linux-vdso.so.1 =>  (0x00007fff705a2000)
    libclntsh.so.12.1 => not found
    libocci.so.12.1 => not found
    libnnz12.so => not found
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fe8d6d49000)
    libm.so.6 => /lib64/libm.so.6 (0x00007fe8d6a46000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe8d6830000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fe8d646f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe8d72e4000)

I have successfully compiled my code. I have created two directories for both the versions of Oracle Instant Client, and added both to LD_LIBRARY_PATH.

The problem is that in the two Oracle Instant Client 11 and 12 directories there are some .so files which having the same name.

Oracle Instant Client 11 libraries :-

libclntsh.so libclntsh.so.11.1 libnnz11.so libocci.so libocci.so.11.1 libociei.so libocijdbc11.so ojdbc5.jar ojdbc6.jar xstreams.jar

Oracle Instant Client 12 libraries :-

libclntshcore.so.12.1 libclntsh.so.12.1 libmql1.so libocci.so.12.1 libociei.so libons.so ojdbc6.jar xstreams.jar libclntsh.so libipc1.so libnnz12.so libocci.so_bkp libocijdbc12.so liboramysql12.so ojdbc7.jar

Libraries having same name: libociei.so etc.

Now, the situation is a .so file from the Oracle 12 client internally calls a .so file which is present in the Oracle 11 client directory. Which .so would be used, because in LD_LIBRARY_PATH both are present?

Alex Poole
  • 183,384
  • 11
  • 179
  • 318
Deepak Kumar
  • 29
  • 1
  • 8
  • It would help to include the commands you're using for the builds, particularly for the linking. It sounds like you want to give different [`-rpath`](http://stackoverflow.com/q/8482152/266304) options. I'm confused though, is your executable using your .so - in which case why are they using different client versions - or are they independent and just have to coexist? Is there a reason not to use the same version for both, even if that means they have to use 11g for now? – Alex Poole Jun 09 '16 at 13:54
  • Hi Alex, the executable is linked using -rpath. The libOracleClient.so is using dlopen and giving the complete path. the exectuable and the libOracleClient.so are two independent things, the executable which i have mentioned is not using libOracleClient.so. I need to upgrade my oracle instant client to latest, so technically both the execuatble and .so file should use the latest version, but the executable is using some other .so i.e libdx_t.so which was linked using the oracle 11 instant client. Thus I need to have both the versions present. – Deepak Kumar Jun 10 '16 at 03:43

1 Answers1

0

A fairly simple approach would be to have your LD_LIBRARY_PATH only refer to the current version 12c library location, and remove the 11g path from it.

Then have a wrapper script (or shell function) that sets the 11g path and calls the executable, say my_exe_wrapper:

export LD_LIBRARY_PATH=/path/to/instant_client_12_1
# add anything else you need in that variable, except the 11g path
/path/to/original_exe

And add an alias so you can still refer to it by the original name:

alias -x original_exe=/path/to/my_exe_wrapper

Now when you run original_exe it will call the wrapper script, which will set the environment variable and call the real executable. That will have no visibility of the 12c libraries, because their path is no longer being searched. And inversely, everything else - including whatever uses libOracleClient.so - will have no visibility of the 11g libraries.

If your LD_LIBRARY_PATH has a lot of entries and you don't want to have to recreate it from scratch, and if the paths to the 11g and 12c library locations are similar, you could use sed to replace just that segment. Say if you'd put them under /opt/instant_client_11_2 and /opt/instant_client_12_1, your wrapper could do:

LD_LIBRARY_PATH =`echo $LD_LIBRARY_PATH | sed -e "s|instant_client_12_1|instant_client_11_2|"`
/path/to/original_exe
Alex Poole
  • 183,384
  • 11
  • 179
  • 318
  • Hi Alex, Thanks for your valuable suggestion. I already know the solution to this issue, which involves code changes. My doubt was to know, what is the preference when dll with same names are present in LD_LIBRARY_PATH, is it that firstly .so is being searched in current directory of the executable and then if not found there it searched from LD_LIBRARY_PATH? – Deepak Kumar Jun 13 '16 at 08:37
  • As far as I'm aware the paths specified by `-rpath` will be used to find both the libraries the executable references directly, and any those depend on - which I think is what the last part of your question is about. And they will take precedence over LD_LIBRARY_PATH - that will be searched if rpath doesn't satisfy a link, in the order they appear in the list; followed by the system library paths.The `ldd` output in your question suggests you didn't build with `-rpath`, and neither Oracle dir is in LD_LIBRARY_PATH. Maybe you didn't export that variable? – Alex Poole Jun 13 '16 at 09:05