Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2009-11

SqlDB + Firebird application doesn't run on new Ubuntu installation

9 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

I previously raised this issue, but nothing came from that message thread.

http://lists.freepascal.org/lists/fpc-devel/2009-August/017296.html

To recap, here is the problem...

I noticed that on newer Ubuntu Linux systems that the name of the Firebird shared library has changed for v2.x versions of Firebird Database Server. Apparently this change in not only limited to Ubuntu, but many other Linux distro's too.

----------------------------------
$ ls -l /usr/lib/libfbcl*
2009-08-24 12:06 /usr/lib/libfbclient.so.2 -> libfbclient.so.2.1.1 2008-11-19 20:09 /usr/lib/libfbclient.so.2.1.1
----------------------------------

The SqlDB + Firebird code only looks for 'libgds.so' and 'libfbclient.so' giving the following error at runtime...

Without the un-versioned symbolic link, SqlDB + Firebird applications will not run, even if the user installed the 'libfbclient2' package.

I was told that only development packages include the un-versioned symbolic link, because only the linker (and other development tools) should be the only apps that use that unversioned library. Applications are supposed to use the versioned libraries instead. See Luca's reply for the full explanation.

http://lists.freepascal.org/lists/fpc-devel/2009-August/017300.html

The work around on the client PC is simple, but I do not think this is the ideal solution - forcing the user to manually create a libfbclient.so symbolic link to the versioned on. And to do that, they must have root privileges!

Possible solutions:
-------------------
1) Change SqlDB + Firebird code to look for 'libfbclient.so.2' by default. After all, version 2 of Firebird has been out for years.

2) Add a extra check in InitialiseIBase60() [ibase60.inc] to check for versioned and un-versioned client libraries. The thirdparty FBLib package used to do this and it worked fine. It doesn't need to check minor versions, only major versions - starting at newest and working back to oldest versions. eg:

if found libfbclient.so.2 then // latest major version of Firebird ...
else if found libfbclient.so.1 then // previous major version ...
else if found libfbclient.so then // finally the unversioned one ...

3) Somehow allow the developer to specify via a SqlDB property which version the initialization code should look for. After all, the developer knows which version of the database server they developed for.

I don't mind creating a patch for option 2 above. Would such a patch be accepted though? It shouldn't break anything - in contrary, it will only improve user experience and less application crashes in deployed software.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 70 lines
Hi, I previously raised this issue, but nothing came from that message thread. http://lists.freepascal.org/lists/fpc-devel/2009-August/017296.html To recap, here is the problem... I noticed that on newer Ubuntu Linux systems that the name of the Firebird shared library has changed for v2.x versions of Firebird Database Server. Apparently this change in not only limited to Ubuntu, but many other Linux distro's too. ---------------------------------- $ ls -l /usr/lib/libfbcl* 2009-08-24 12:06 /usr/lib/libfbclient.so.2 -> libfbclient.so.2.1.1 2008-11-19 20:09 /usr/lib/libfbclient.so.2.1.1 ---------------------------------- The SqlDB + Firebird code only looks for 'libgds.so' and 'libfbclient.so' giving the following error at runtime... Without the un-versioned symbolic link, SqlDB + Firebird applications will not run, even if the user installed the 'libfbclient2' package. I was told that only development packages include the un-versioned symbolic link, because only the linker (and other development tools) should be the only apps that use that unversioned library. Applications are supposed to use the versioned libraries instead. See Luca's reply for the full explanation. http://lists.freepascal.org/lists/fpc-devel/2009-August/017300.html The work around on the client PC is simple, but I do not think this is the ideal solution - forcing the user to manually create a libfbclient.so symbolic link to the versioned on. And to do that, they must have root privileges! Possible solutions: ------------------- 1) Change SqlDB + Firebird code to look for 'libfbclient.so.2' by default. After all, version 2 of Firebird has been out for years. 2) Add a extra check in InitialiseIBase60() [ibase60.inc] to check for versioned and un-versioned client libraries. The thirdparty FBLib package used to do this and it worked fine. It doesn't need to check minor versions, only major versions - starting at newest and working back to oldest versions. eg: if found libfbclient.so.2 then // latest major version of Firebird ... else if found libfbclient.so.1 then // previous major version ... else if found libfbclient.so then // finally the unversioned one ... 3) Somehow allow the developer to specify via a SqlDB property which version the initialization code should look for. After all, the developer knows which version of the database server they developed for. I don't mind creating a patch for option 2 above. Would such a patch be accepted though? It shouldn't break anything - in contrary, it will only improve user experience and less application crashes in deployed software.

Please create a patch.

Note that it is already possible to tell initialiseIBase60 which library it should load, so it's possible to do a workaround.

Michael.

Reply by email

Joost van der Sluis
to Graeme Geldenhuys: I previously raised this issue, but nothing came from that message thread.…
Graeme Geldenhuys wrote
I noticed that on newer Ubuntu Linux systems that the name of the Firebird shared library has changed for v2.x versions of Firebird Database Server. Apparently this change in not only limited to Ubuntu, but many other Linux distro's too.

As I see it it's a Ubuntu-bug. They are too strict on their packages rules, because this does not apply to Firebird.

Besides, for fpc this is a nightmare to maintain, because we have to search for all versions of a specific library. This behaviour is only valid if all your programs are compiled for the specific distribution.

Maybe that can be often the case on linux because you can compile applications yourself. But this aint good. And our buildtools don't take care of this...

Offcourse, a patch is welcome. (althoug a maintenance nightmare) But you can also add a call to the initialize function of interbase in your program with the right library name as parameter.

Joost.

Reply by email

Graeme Geldenhuys
to Joost van der Sluis

2009/11/26 Joost van der Sluis :

As I see it it's a Ubuntu-bug. They are too strict on their packages rules, because this does not apply to Firebird.

I was told that this is not just a Ubuntu issue though - but I could only test with Ubuntu because that is what we use in our company. Also considering that Ubuntu is the most popular Linux distro for some time
- it should be ok to cater for them. The end result is what is important - less issues for the end-user, which would not really care or know about the technical reasons why there are versioned and unversioned library symlinks. They installed the Firebird v2 client library as mentioned in the prerequisites document of the app, so should not be expected to still go fiddle with symbolic links which require root access too.

Besides, for fpc this is a nightmare to maintain, because we have to search for all versions of a specific library.

Why? I'm only mentioning Firebird. And from what I can see, you only need to look for major version numbers of libraries in this case, not every minor number. FPC already checks for the very outdated 'libgds.so', so why the issue with 'libfbclient.so.2'?

Offcourse, a patch is welcome.

I'll supply a patch tomorrow... When I'm back at work tomorrow, I'll also take a look at the initialize function you an Michael mentioned, to see if I can improve anything from the application side.

From the application side (well in our case), the application can

switch at runtime between various database backends because the application doesn't actually do the database communication, it's the job of the OPF framework we use. Our application simply supplies the connection string: database server location, database name, username & password.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Marco van de Voort
to Graeme Geldenhuys: I previously raised this issue, but nothing came from that message thread.…

In our previous episode, Graeme Geldenhuys said:

Show quoted text 8 lines
the ideal solution - forcing the user to manually create a libfbclient.so symbolic link to the versioned on. And to do that, they must have root privileges! Possible solutions: ------------------- 1) Change SqlDB + Firebird code to look for 'libfbclient.so.2' by default. After all, version 2 of Firebird has been out for years.

Best. Or simply use the static ones and -XLA.

If you use the static units, a simple -XLAfbclient=fpbclient.2 might solve this too.

2) Add a extra check in InitialiseIBase60() [ibase60.inc] to check for versioned and un-versioned client libraries

This is a bit of a slippery slope. This kind of autodetections always have a certain percentage of failures and dubious cases. (what if multiple versions are in the path? what if .3 comes out? The FPC release could become unusable)

In such case, the main program should be able to initialize the library, and left to the application builder, which can then adapt in case of problems without needing a new toolchain.

Today it is fbclient, and tomorrow we have detection code with multiple cases names, paths etc for every library on an Unix system.

Reply by email

Michael Van Canneyt
to Marco van de Voort
Marco van de Voort wrote 15 lines
In our previous episode, Graeme Geldenhuys said: > the ideal solution - forcing the user to manually create a > libfbclient.so symbolic link to the versioned on. And to do that, they > must have root privileges! > Possible solutions: > ------------------- > 1) Change SqlDB + Firebird code to look for 'libfbclient.so.2' by > default. After all, version 2 of Firebird has been out for years. Best. Or simply use the static ones and -XLA. If you use the static units, a simple -XLAfbclient=fpbclient.2 might solve this too.

But then it fails on a Firebird 1.5 installation, and there are a lot of those around as well.

The patch as Graeme suggests is good, and will solve 99% of all cases. For the corner cases that still go wrong, the programmer can fix it by explicitly detecting and loading the correct one at program startup.

Michael.

Reply by email

Graeme Geldenhuys
to Graeme Geldenhuys: I previously raised this issue, but nothing came from that message thread.…

OK, below is one example of a patch, but there are alternative methods too, hence I am first posting here in the mailing list before I officially put something in Mantis.

In the example below (which does work) I simply test for the newest major version first, then un-versioned, then backward compatibility library.

----------------------------------------
diff --git a/packages/ibase/src/ibase60.inc b/packages/ibase/src/ibase60.inc index 5bc668d..54e2ab3 100644
--- a/packages/ibase/src/ibase60.inc
+++ b/packages/ibase/src/ibase60.inc
@@ -2647,8 +2647,9 @@ begin

     end
   else
     begin

- If (TryInitialiseIBase60(fbclib)=0) and
- (TryInitialiseIBase60(gdslib)=0) then
+ If (TryInitialiseIBase60(fbclib+'.2')=0) and // major versioned
+ (TryInitialiseIBase60(fbclib)=0) and // un-versioned
+ (TryInitialiseIBase60(gdslib)=0) then // backward compatibility

         Raise EInOutError.CreateFmt(SErrDefaultsFailed,[gdslib,fbclib]);
     end;
   Result := RefCount;

----------------------------------------

What I don't like about the patch above, is the 'and' statement. Wouldn't it be better (optimised) to do the following:

if not v2 found then // libfbclient.so.2 if not unversioned found then // libfbclient.so if not gds found then // libgds.so
raise Exception.Create(...)

That way it will stop at the first if that found a valid library. Yet another alternative to the above if statement, is to test for the unversioned library first - this should make Joost happy & non-Ubuntu installs. That way DB developers could simply adjust the unversioned library symlink (libfbclient.so) and FPC would automatically load the developers desired version of the library. I think this is the best option so far. eg:

if not unversioned found then // libfbclient.so if not v2 found then // libfbclient.so.2 if not gds found then // libgds.so
raise Exception.Create(...)

Your thoughts?

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 52 lines
OK, below is one example of a patch, but there are alternative methods too, hence I am first posting here in the mailing list before I officially put something in Mantis. In the example below (which does work) I simply test for the newest major version first, then un-versioned, then backward compatibility library. ---------------------------------------- diff --git a/packages/ibase/src/ibase60.inc b/packages/ibase/src/ibase60.inc index 5bc668d..54e2ab3 100644 --- a/packages/ibase/src/ibase60.inc +++ b/packages/ibase/src/ibase60.inc @@ -2647,8 +2647,9 @@ begin end else begin - If (TryInitialiseIBase60(fbclib)=0) and - (TryInitialiseIBase60(gdslib)=0) then + If (TryInitialiseIBase60(fbclib+'.2')=0) and // major versioned + (TryInitialiseIBase60(fbclib)=0) and // un-versioned + (TryInitialiseIBase60(gdslib)=0) then // backward compatibility Raise EInOutError.CreateFmt(SErrDefaultsFailed,[gdslib,fbclib]); end; Result := RefCount; ---------------------------------------- What I don't like about the patch above, is the 'and' statement. Wouldn't it be better (optimised) to do the following: if not v2 found then // libfbclient.so.2 if not unversioned found then // libfbclient.so if not gds found then // libgds.so raise Exception.Create(...) That way it will stop at the first if that found a valid library. Yet another alternative to the above if statement, is to test for the unversioned library first - this should make Joost happy & non-Ubuntu installs. That way DB developers could simply adjust the unversioned library symlink (libfbclient.so) and FPC would automatically load the developers desired version of the library. I think this is the best option so far. eg: if not unversioned found then // libfbclient.so if not v2 found then // libfbclient.so.2 if not gds found then // libgds.so raise Exception.Create(...) Your thoughts?

I'd use an array of library names and a for loop.
It is easier to extend. You can add fbclient.1 and fbclient.3 to the array.

Michael.

Reply by email

Jonas Maebe
to Graeme Geldenhuys: OK, below is one example of a patch, but there are alternative methods too, hence I am…
Graeme Geldenhuys wrote 32 lines
diff --git a/packages/ibase/src/ibase60.inc b/packages/ibase/src/ ibase60.inc index 5bc668d..54e2ab3 100644 --- a/packages/ibase/src/ibase60.inc +++ b/packages/ibase/src/ibase60.inc @@ -2647,8 +2647,9 @@ begin end else begin - If (TryInitialiseIBase60(fbclib)=0) and - (TryInitialiseIBase60(gdslib)=0) then + If (TryInitialiseIBase60(fbclib+'.2')=0) and // major versioned + (TryInitialiseIBase60(fbclib)=0) and // un-versioned + (TryInitialiseIBase60(gdslib)=0) then // backward compatibility Raise EInOutError.CreateFmt(SErrDefaultsFailed, [gdslib,fbclib]); end; Result := RefCount; ---------------------------------------- What I don't like about the patch above, is the 'and' statement. Wouldn't it be better (optimised) to do the following: if not v2 found then // libfbclient.so.2 if not unversioned found then // libfbclient.so if not gds found then // libgds.so raise Exception.Create(...) That way it will stop at the first if that found a valid library.

The first form will do that as well. See "short-circuit evaluation" at http://www.freepascal.org/docs-html/ref/refsu31.html

Jonas

Reply by email