Recent

Author Topic: [SOLVED] Unable to connect at run-time with Firebird 3.0 embedded and IBX  (Read 580 times)

devEric69

  • Full Member
  • ***
  • Posts: 121
Hello,

(my configuration:
- Untunu 18.04
- Lazarus 1.8.5 + FPC 3.0.5 + Firebird IBX 2.3.2 but I think that TIBTransaction has nothing to do with it)


I would like to make an application with Firebird 3.0 embedded. I use IBX components.
I have put in the project directory, all the files (these are the files to deliver, and others just in case...) like this:

/home/.../project1/
|-- database.fdb
|-- project1 (application)
|
|
|-- databases.conf
|-- fbintl.conf
|-- fbtrace.conf
|-- firebird.conf
|-- plugins.conf
|-- firebird.msg
|-- @libfbclient.so (symlink "soft" towards @libfbclient.so.2)
|-- @libfbclient.so.2 (symlink "soft" towards libfbclient.so.3.0.3)
|-- libfbclient.so.3.0.3 (true librairy)
|
└--/intl/
| |-- fbintl.conf
| |-- libfbintl.so
|•
|
└--/plugins/
| |-- libEngine12.so
| |-- libfbtrace.so
|•
|


I put the following code that opens the connection... :
Code: Pascal  [Select]
  1. procedure TfrmMain.btnOpenCnxClick(Sender: TObject);
  2. begin
  3.   with IBDatabase1 do begin
  4.        DatabaseName:= '/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/database.fdb';
  5.        FirebirdLibraryPathName:= '/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/libfbclient.so.3.0.3';
  6.        Connected:= true;
  7.   end;
  8.   IBTransaction1.Active:= true;
  9.   IBTable1.Active:= true;
  10. end;

When I launch the program compiled outside Lazarus (by double-clicking on the "project1" executable), the connection opens correctly :) . I am happy.

➔ Now, I would like to know exactly which Firebird 3.0 libraries are used by the Project1 application:
- fbguard and firebird services are not loaded (the command "top -b -n1 | grep[f]irebird" returns nothing; that's good, because the documentation says about the embedded version, that there is no need for the firebird executable).
- when I issue these commands in succession... :
Code: Pascal  [Select]
  1. pidof /home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/project1
and
Code: Pascal  [Select]
  1. lsof -p pid_9999_pid|grep mem
... which returns the libraries used by the application project1 (I have circled those that should make the embedded package to be delivered, if I have understood the documentation correctly), I get the list (see file Laz2_usedLibraries.png).

Well, what bothers me, it is that I would like to deliver everything, executable and Firebird libraries, in the same directory where the application will be installed. In other words, I would like to load the libraries that are in /home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1.


➔ To do this, I have made the following changes:
- I've added environment variables that are surrounded in the screenshot. NB: I also created a FBLIB environment variable as indicated in the very complete IBX documentation, but I think TIBTransaction is absolutely not involved. My environment variables are (visible with the bash cmd "printenv"):
LD_LIBRARY_PATH=:/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1:/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/plugins
FIREBIRD=/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1
FBLIB=/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1

- I've modified the file /home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/firebird.conf by adding:
  • RootDirectory=/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1
  • DatabaseAccess = Full
  • ExternalFileAccess = Full
  • UdfAccess = Full
  • Providers = Engine12
  • ServerMode = Classic
- I've renamed the directory /usr/lib/x86_64-linux-gnu/firebird/3.0/... to /usr/lib/x86_64-linux-gnu/firebird/6.0/... hoping to force to specifically load the libraries that are in my application directory. But when I launch the application (always at the run-time), I get the following results: ==> the connection refuses to be established at run-time.

The only library loaded by the application is /home/guepard/SauveWine_etc/a_projectLaz/dir_project_num1/libfbclient.so.3.3. That's all  :( . ==>The libraries /usr/.../3.0/plugins/libfbtrace.so, /usr/.../3.0/plugins/libfengine12.so (!!?), and /usr/.../3.0/intl/libfbintl.so are not loaded :-\.


Already here, I'm surprised that the environment variables I have added (variables that are supposed to indicate where Firebird libraries are, especially for those needed for an "embedded" mode) do not allow to load these *.SOs (including /home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/plugins/libengine12.so)?!!


➔ So, I've added code to dynamically load them, just before the IBX's connection attempt:
Code: Pascal  [Select]
  1. uses dynlibs;
  2.  
  3. .../...
  4.  
  5. procedure TfrmMain.btnOpenCnxClick(Sender: TObject);
  6.  const csPathLibraryLocation_Firebird3_1 = '/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/plugins/libEngine12.so';
  7.        csPathLibraryLocation_Firebird3_2 = '/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/plugins/libfbtrace.so';
  8.        csPathLibraryLocation_Firebird3_3 = '/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/intl/libfbintl.so';
  9.  var
  10.  sExceptionMsg: string;
  11.  hDLL_Firebird3_1, hDLL_Firebird3_2, hDLL_Firebird3_3: TLibHandle;
  12.    ptrDB: Pointer;
  13.  iDLL_Func_res: integer;
  14. begin
  15.   hDLL_Firebird3_1:= NilHandle; hDLL_Firebird3_2:= NilHandle; hDLL_Firebird3_3:= NilHandle;
  16.   hDLL_Firebird3_1:= SafeLoadLibrary(csPathLibraryLocation_Firebird3_1);
  17.   if (hDLL_Firebird3_1 = dynlibs.NilHandle) then begin
  18.      sExceptionMsg:= 'Library ' + csPathLibraryLocation_Firebird3_1 + 'not launched!';
  19.      raise Exception.Create(sExceptionMsg)
  20.   end;
  21.   hDLL_Firebird3_2:= SafeLoadLibrary(csPathLibraryLocation_Firebird3_2);
  22.   if (hDLL_Firebird3_2 = dynlibs.NilHandle) then begin
  23.      sExceptionMsg:= 'Library ' + csPathLibraryLocation_Firebird3_2 + 'not launched!';
  24.      raise Exception.Create(sExceptionMsg)
  25.   end;
  26.   hDLL_Firebird3_3:= SafeLoadLibrary(csPathLibraryLocation_Firebird3_3);
  27.   if (hDLL_Firebird3_3 = dynlibs.NilHandle) then begin
  28.      sExceptionMsg:= 'Library ' + csPathLibraryLocation_Firebird3_3 + 'not launched!';
  29.      raise Exception.Create(sExceptionMsg)
  30.   end;
  31.  
  32.   with IBDatabase1 do begin
  33.        DatabaseName:= '/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/database.fdb';
  34.        FirebirdLibraryPathName:= '/home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/libfbclient.so.3.0.3';
  35.        Connected:= true;
  36.   end;
  37.   IBTransaction1.Active:= true;
  38.   IBTable1.Active:= true;
  39. end;  
==> Same disappointing result (Exception) when I click on the button to open the connection...
... yet, the libraries are well loaded from my directory (!!?): see file Laz7_loaded_libraries.png.

==> What am I doing wrong? Does anyone see, have an idea, how I am hurting to not succeed in loading libEngine12.so in a "canonical" way and that is functional in order to establish a real embedded connection worthy of the name, from /home/guepard/SauveWinE_etc/a_projetsLaz/dir_project_num1/plugins/libEngine12.so (an embedded installation should allow this, and simplify \ lighten the creation of an installation package)?

Regards.
« Last Edit: April 24, 2019, 03:47:10 pm by devEric69 »
use: Ubuntu 18.04 + Laz. 1.8.5 + FPC 3.0.5 (64 bits).

tonyw

  • Full Member
  • ***
  • Posts: 141
    • MWA Software
Re: Unable to connect at run-time with Firebird 3.0 embedded and IBX
« Reply #1 on: April 04, 2019, 06:17:45 pm »
First, you should noted that  the environment variable "FBLIB" overrides the IBDatabase1.FirebirdLibraryPathName setting. If you using FirebirdLibraryPathName then you should not set FBLIB.

You can also use IBDaatbase1.FirebirdAPI.GetFBLibrary.GetLibraryFilePath to find out the actual location of the Firebird client library.

Otherwise, your problem seems to relate to the location of the Firebird libraries. I am not completely certain about this, but under Linux their pathnames may be compiled into the Firebird Client library. Hence, changing their location is going to give a problem.

There is also very little value in changing the firebird.conf params for embedded mode as it directly accesses the database and uses the file system to control permissions. There is no concept of (e.g.) classic mode when you are running embedded.




devEric69

  • Full Member
  • ***
  • Posts: 121
Re: Unable to connect at run-time with Firebird 3.0 embedded and IBX
« Reply #2 on: April 04, 2019, 07:20:15 pm »
Hello,

Thank you for the answer.
I will look at the different tracks mentioned.

There is indeed one that I fear (for the possibility of creating a simple installation package): Firebird libraries compiled for *.nix with a hard path written in them.
I will post the feedback, on what I will found.

Regards.
use: Ubuntu 18.04 + Laz. 1.8.5 + FPC 3.0.5 (64 bits).

tonyw

  • Full Member
  • ***
  • Posts: 141
    • MWA Software
Re: Unable to connect at run-time with Firebird 3.0 embedded and IBX
« Reply #3 on: April 05, 2019, 12:20:55 am »
The approach I use is to package my app in a .deb for Ubuntu and  give the firebird package(s) as dependencies. That way you always get the up-to-date Firebird binaries as provided by your distro. IBX  will find them automatically , without you setting the library path. For the embedded server you only need the common package as you do  not need a full server.

This contrasts with Windows where your installation package must itself include the Firebird binaries.

devEric69

  • Full Member
  • ***
  • Posts: 121
Re: Unable to connect at run-time with Firebird 3.0 embedded and IBX
« Reply #4 on: April 24, 2019, 03:46:52 pm »
Quote
Sinon, votre problème semble être lié à l'emplacement des bibliothèques Firebird. Je n'en suis pas tout à fait certain, mais sous Linux leurs noms de chemin peuvent être compilés dans la bibliothèque Firebird Client. Par conséquent, changer leur emplacement va poser un problème.

That's what I think too, because then commands... $ readelf -d libEngine12.so | grep -i RPATH , or $ readelf -d libfbclient.so.2 | grep -i RUNPATH ...  didn't return any fields (RPATH or RUNPATH) with a hard path (I didn't have the courage to write a *.sh script to parse like this all Firebird librairies ::) ).

On the other hand, ldconfig -p sends me back...:
.../...
libfbclient.so.2 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libfbclient.so.2
libtommath.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libtommath.so.1
.../...
...as expected.

To conclude, I've come to think that, there are 2 steps to consider completely separately in Linux+Firebird-embedded development:
- that the installation from the repositories (or even the installation of "-dev" packages in addition if "soft symlink" is missing) is a good thing to be able to write an application with Firebird from Lazarus on its distribution.
- once the application is finished, I will uninstall everything about Firebird, and from the content of the download of its *.tar.gz, I will create a client installation with AppImage + its yaml scripts (my choice).

▶ PS: the IBX component suite is completely neutral in this problem; I just have an affinity with IBX which because of its properties, shows that this suite has pushed the understanding of Firebird's internal workings further than others; this very small troll with IBX has allowed me to get an expert opinion ;) ).

Honestly, I think that the ELF's program loader ( ld-linux.so.X ) on Linux idiosyncrasy, would require an evolution that would make Linux as convenient as Windows from the point of view of desktop developments, i. e. starting by first looking in the same directory as the loaded application, if the NEEDED library would not be there, by the best of luck.
use: Ubuntu 18.04 + Laz. 1.8.5 + FPC 3.0.5 (64 bits).