Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Locating/Linking NWRFC libraries

richard_gray
Explorer
0 Kudos

We have converted code which used to use the classic RFC libraries to use the Netweaver RFC libraries.  Because we are doing BC-XOM, we are executing outside of SAP and often we are executing on a server which does not host an SAP system. 

The switch from having the RFC library available in archive form (.a) to shared objects may make good sense to SAP and many of its users, but is problematic to us.  With the archive form, we were able to statically link the library to our program which performs  callbacks and that was that.  The program installed on a customer's machine and ran - no problem.   With NWRFC, we are forced to link against libraries that are beyond our control.  This causes potential stability problems.  If the loader can't find the libraries, the program using them will simply fail to load and run.  This program has other responsibilites besides SAP callbacks, so its failure has effects beyond loss of SAP function.   We understand we can't redistribute RFC library binaries, so it is up to the customer to have them "properly" installed, even on non-SAP systems.

Issues:

  • Where is the proper place to install/find these libraries on SAP systems?

  • Should they already be there on an SAP system?

  • Is there a defined, programatic way for a non-SAP program to locate the RFC libraries at install time or run time??   Do SAP systems always install at /usr/sap/SID or c:\SAP\SID ?  (Guessing no...)

http://service.sap.com/sap/support/notes/1739797 says libraries should be placed into the DIR_EXECUTABLE directory.  On our Linux testdrive system, I see RFC library files in /usr/sap/NPL/DVEBMGS42/exe and /usr/sap/NPL/SCS00/exe.   There's a poor match between the  library files in the RFCSDK and the exe directories:

  /usr/sap/NPL/DVEBMGS42/exe # ls libicudata* libicudecnumber* libicui18n* libicuuc* libsapnwrfc* libsapucum*

  ls: cannot access libicudecnumber*: No such file or directory

  ls: cannot access libsapucum*: No such file or directory

  libicudata.so.34  libicui18n.so.34  libicuuc.so.34  libsapnwrfc.so

I imagine the .sl.34 and .so.34 difference will be internally resolved.  The absence of libsapucum and libicudecnumber concerns me because I'm supposed to link against those, right??   This test system is 3 years old... Guess I need to grab a current trial.  Are we likely to get into trouble with trying to user older versions when compiled against a current library set??  I'm guessing we will not run pointed at the above directories.  (I've been developing with the 720 patch 38 libraries.)

  • Any recommendations installing on a non-SAP system?   I'm guessing that one should just follow the system guidelines for adding a library in a system directory or create a new directory and add it to the system search path.  Or put the libraries in our binaries directory if I can get the library search path to point there.

  • Are there linker options for "lazy" runtime binding? In such a mode, references aren't resolved until they are actually encountered.  So, if the program is not doing SAP things, it never hits the RFC calls and does not die if the libraries aren't right.  I haven't found anything workable.

  • Linker path options?   I've played with the option RPATH (-rpath) to try to add the directory our binaries are in to the library search path.  Unfortunately, our binary is setuid and that disables options like RPATH or environment variables like LD_LIBRARY_PATH for security reasons.  Given that at link time we don't know where our application or the RFC libraries will reside, linker path options don't seem likely to be of much use.

At this point, I've decided to try using the dlopen(), dlsym() and dlclose() routines to manage the loading of the RFC libraries under program control.  I will define function pointers to all RFC functions that we call, then use dlsym() to set them.  I may be able to use macros to make the pointers appear under their normal function names, making the whole dynamic load thing transparent to the rest of the application.  This should keeps the program self contained and avoid crashing if the libraries don't load.   It also allows controlled searching of SAP directories (if there is a programatic way to determine where SAP keeps the RFC libraries.)  The simple fallback will be to look in our own binaries directory, so the customer always has the simple option of plopping the RFC library files in there, or placing symlinks to the actual libraries.   Maybe a symlink to the library directory...

Any suggestions would be greatly appreciated!  If I've posted this in the wrong area please let me know so I can repost to the right place.

Thanks!

Rich

1 ACCEPTED SOLUTION

Ulrich_Schmidt
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Rich,

well, this is a long post. I think I can answer some of the questions:


> Where is the proper place to install/find these libraries on SAP systems?

Originally, these libraries were meant for usage by external programs, so they were not shipped/installed with the SAP System. Users who needed them for their programs would have to download and install them. The place, where they are installed, does not matter, because in my opinion adding the lib directory of the SDK to the LD_LIBRARY_PATH should be part of that "installation process".

However, starting with SAP Kernel 7.40, the NW RFC libraries have now been added to the kernel, so they can indeed be found in the DIR_EXECUTABLE directory of the SAP system. Please note: note 1739797 is not about the NW RFC SDK or the SAP Kernel, it is about the Internet Graphics Server (IGS), which already required the NW RFC libs before Release 7.40, so made this "special solution" for IGS running on SAP Systems < 7.40.


I think this also answers the next two questions. Basically the simplest solution for you would be:

  • If running on a SAP system with Kernel 7.40 or higher, the libraries are already there and can be found in DIR_EXECUTABLE. (Note that the current "backward compatible kernel" used by all SAP systems of Release 7.4x is 7.42. So if the customer has not fallen too far behind with applying the regular kernel patch levels, you can expect the libraries to be there on all systems > 7.20.)
  • If running on an older SAP system (4.6D, 6.20, 6.40, 7.00, 7.20 - I don't expect any older systems to be still in use these days) or on a standalone server, your customer would have to download and extract the SDK as described in note 1025361, and add the lib subdirectory to the LD_LIBRARY_PATH. I think, if you document this clearly in the installation instructions of your product, it should not be too much of a problem andf you can take it for granted?!

One special comment regarding libicudecnumber: if your program does not process function modules that have parameters of type DECFLOAT, then you don't need this library. It is independent of the other libraries, so you also don't need to link it at all. (A bit of background: there are two DECFLOAT types, a 16bit and a 34bit version, originally introduced by IBM DB2. In one of the recent SAP Kernel releases it was also added as a new ABAP data type. As of today, only a very small number of applications use this type, and fewer still use it in an RFC interface. So most probably you won't need it.)

(PS: libicudecnumber.so is not shipped with the kernel. Aparrently none of the helper executable needs it, and the kernel has linked it statically. So if you do need to process DECNUMBER values, you will depend on the NW RFC SDK being installed separately on any host.)

> Are there linker options for "lazy" runtime binding?

I would expect that this is highly platform-dependent... In any case, the NW RFC lib doesn't have any special support for it (even if it would be possible on all platforms that we support).

> Unfortunately, our binary is setuid and that disables options like RPATH or environment
> variables like LD_LIBRARY_PATH for security reasons.

Now this is indeed a difficult problem. I don't know an easy solution either, but to be honest: the dlopen() approach is ugly and cumbersome, isn't it? Anything would be better than this! But even setuid processes are allowed to load libraries from the standard directories like /usr/lib, so one option would be to copy the NW RFC libs there (or create symlinks).

And I found the following very interesting & instructive article, which documents two methods that should work on Linux (not sure about the various Unixes, though):

  • Include the NW RFC lib directory in the file /etc/ld.so.conf. Then even setuid processes will find and load them!
  • Alternatively: when starting the process, make sure that the uid and effective uid (as well as gid and effective gid) are equal. (So basically root needs to become the file owner of your binary.) Then LD_LIBRARY_PATH will be used for loading shared libs, even if the process runs as root!

See the following article for the details: Library Linking and setuid executables - Kevin R Tower - UW Information Technology Wiki

Hope I was able to help a bit.

Best regards, Ulrich

Message was edited by: Ulrich Schmidt - Correction about backward compatible kernel. - libicudecnemuber not distributed with the kernel.

1 REPLY 1

Ulrich_Schmidt
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Rich,

well, this is a long post. I think I can answer some of the questions:


> Where is the proper place to install/find these libraries on SAP systems?

Originally, these libraries were meant for usage by external programs, so they were not shipped/installed with the SAP System. Users who needed them for their programs would have to download and install them. The place, where they are installed, does not matter, because in my opinion adding the lib directory of the SDK to the LD_LIBRARY_PATH should be part of that "installation process".

However, starting with SAP Kernel 7.40, the NW RFC libraries have now been added to the kernel, so they can indeed be found in the DIR_EXECUTABLE directory of the SAP system. Please note: note 1739797 is not about the NW RFC SDK or the SAP Kernel, it is about the Internet Graphics Server (IGS), which already required the NW RFC libs before Release 7.40, so made this "special solution" for IGS running on SAP Systems < 7.40.


I think this also answers the next two questions. Basically the simplest solution for you would be:

  • If running on a SAP system with Kernel 7.40 or higher, the libraries are already there and can be found in DIR_EXECUTABLE. (Note that the current "backward compatible kernel" used by all SAP systems of Release 7.4x is 7.42. So if the customer has not fallen too far behind with applying the regular kernel patch levels, you can expect the libraries to be there on all systems > 7.20.)
  • If running on an older SAP system (4.6D, 6.20, 6.40, 7.00, 7.20 - I don't expect any older systems to be still in use these days) or on a standalone server, your customer would have to download and extract the SDK as described in note 1025361, and add the lib subdirectory to the LD_LIBRARY_PATH. I think, if you document this clearly in the installation instructions of your product, it should not be too much of a problem andf you can take it for granted?!

One special comment regarding libicudecnumber: if your program does not process function modules that have parameters of type DECFLOAT, then you don't need this library. It is independent of the other libraries, so you also don't need to link it at all. (A bit of background: there are two DECFLOAT types, a 16bit and a 34bit version, originally introduced by IBM DB2. In one of the recent SAP Kernel releases it was also added as a new ABAP data type. As of today, only a very small number of applications use this type, and fewer still use it in an RFC interface. So most probably you won't need it.)

(PS: libicudecnumber.so is not shipped with the kernel. Aparrently none of the helper executable needs it, and the kernel has linked it statically. So if you do need to process DECNUMBER values, you will depend on the NW RFC SDK being installed separately on any host.)

> Are there linker options for "lazy" runtime binding?

I would expect that this is highly platform-dependent... In any case, the NW RFC lib doesn't have any special support for it (even if it would be possible on all platforms that we support).

> Unfortunately, our binary is setuid and that disables options like RPATH or environment
> variables like LD_LIBRARY_PATH for security reasons.

Now this is indeed a difficult problem. I don't know an easy solution either, but to be honest: the dlopen() approach is ugly and cumbersome, isn't it? Anything would be better than this! But even setuid processes are allowed to load libraries from the standard directories like /usr/lib, so one option would be to copy the NW RFC libs there (or create symlinks).

And I found the following very interesting & instructive article, which documents two methods that should work on Linux (not sure about the various Unixes, though):

  • Include the NW RFC lib directory in the file /etc/ld.so.conf. Then even setuid processes will find and load them!
  • Alternatively: when starting the process, make sure that the uid and effective uid (as well as gid and effective gid) are equal. (So basically root needs to become the file owner of your binary.) Then LD_LIBRARY_PATH will be used for loading shared libs, even if the process runs as root!

See the following article for the details: Library Linking and setuid executables - Kevin R Tower - UW Information Technology Wiki

Hope I was able to help a bit.

Best regards, Ulrich

Message was edited by: Ulrich Schmidt - Correction about backward compatible kernel. - libicudecnemuber not distributed with the kernel.