FirebirdSQL / jaybird

JDBC driver for Firebird
https://www.firebirdsql.org/en/jdbc-driver/
GNU Lesser General Public License v2.1
90 stars 23 forks source link

Path to fbclient.dll in connection properties? #745

Closed fdcastel closed 1 year ago

fdcastel commented 1 year ago

Shouldn't exist a connection property to inform the fbclient.dll path?

https://github.com/FirebirdSQL/jaybird/wiki/Connection-properties

I need to run code against different Firebird versions. I have the binaries of each version in distinct folders in my machine.

How could I use jaybird with these different versions?

mrotteveel commented 1 year ago

Normal operation of Jaybird, using the jdbc:firebirdsql:// or jdbc:firebird:// JDBC URLs, does not use fbclient.dll, as Jaybird has a pure Java implementation of the Firebird wire protocol, and can connect to any Firebird version (though future Jaybird 6 will by default only allow connections to supported versions, i.e. Firebird 3.0 or higher).

The fbclient.dll library is only used when using a jdbc:firebirdsql:native:, jdbc:firebirdsql:local: or jdbc:firebirdsql:embedded: (or jdbc:firebird:<{native|local|embedded}>) URL. For non-embedded connections, using the latest fbclient.dll is sufficient. A Firebird 4.0 fbclient.dll can connect to Firebird 1.0 or higher (assuming you use TCP/IP connections).

In other words, for most uses of Jaybird, there is no need for a fbclient.dll. And where it is needed (when you want to use embedded of a specific version), it must be done through the jna.library.path system property before Jaybird or at least the first native/embedded connection is loaded, or by using a native library dependency like jaybird-fbclient, as documented at NATIVE and LOCAL types.

Specifying a library version per connection would be nice, but cannot be achieved: the first fbclient.dll loaded is the one that will be used, and as far as I'm aware, JNA and Java cannot load multiple instances of the library.

mrotteveel commented 1 year ago

The alternative to specifying the location in jna.library.path is making sure that the desired Firebird installation directory (3.0 or higher) or Firebird embedded directory (2.5 or lower) is on the PATH before %WINDIR%\System32, or - if you want/need it to be after - that no fbclient.dll is installed in Windows System32.

mrotteveel commented 1 year ago

If you're using Jaybird 5 or higher, you can also look at creating an embedded locator service provider library as described in jdp-2020-05: Firebird Embedded locator service provider, and example implementation https://github.com/mrotteveel/jaybird-embedded-win32-x86-64/ (NOTE: The example implementation includes the files in the JAR, but it should be possible to write one that refers to files on your local system). However, this will still have the limitation that you cannot load multiple fbclient.dlls within the same process.

mrotteveel commented 1 year ago

If you want to access multiple Firebird server versions from within the same process, you'll need to run multiple servers, each on a different port, or - at least for 3.0 and higher - configure a Firebird 4.0 server, so it also has the engine12.dll of Firebird 3.0, and applies it correctly (I don't have experience with this though).

mrotteveel commented 1 year ago

To come back to the original point: adding a connection property for this would result in wrong expectations, because it would not result in a connection-specific configuration: the first native connection loaded within the process would determine the actual library loaded and used for all connections, ignoring the value configured for later connections.

fdcastel commented 1 year ago

Thank you @mrotteveel for the detailed explanations.

I was not aware that Jaybird had an implementation of the Firebird wire protocol. I understood what you said and the entire explanation makes sense to me.

I'm not a Java developer. I came here basically because of this issue which (I presume) was being caused by jaybird.

Even after all this I'm still unable to make it work. But now I believe it may be something related to the application code.

What I did until now:

In every case I always get the same error:

Unable to complete network request to host "xnet://Global\FIREBIRD". [SQLState:08006, ISC error code:335544721]

Which seems to indicate that the application is trying to connect to a local Firebird server installed on my machine. And NOT using the embedded server.

The "Driver settings" also have an "Embedded" checkbox, but it appears to do nothing in any case.

Thank you, once again. I will wait for DBeaver developers now.

mrotteveel commented 1 year ago

I've reopened this issue. I'll play around with DBeaver using Firebird embedded to see if I can come up with what needs to be done for it to work. However, as I also commented there, the problem is that a fbclient.dll got loaded which doesn't have an embedded engine. The workaround would at least be to either configure the PATH before loading DBeaver, or to see if you can configure the VM options of DBeaver to add -Djna.library.path=<path-to-firebird-directory> to it.

I'll also reconsider if adding a connection property (maybe with an obscure name like iknowwhatimdoing01) at least as a workaround is an option.

fdcastel commented 1 year ago

Mark. If it helps this repo have all needed binaries for each Firebird version ready to use.

mrotteveel commented 1 year ago

Thanks, but I already have all latest releases of Firebird 1.0 - 4.0 (+ 5.0 snapshots) on my machine for testing purposes.

mrotteveel commented 1 year ago

I've decided not to give it an obscure name, but instead will call it nativeLibraryPath. Proposal: https://github.com/FirebirdSQL/jaybird/blob/master/devdoc/jdp/jdp-2023-10-specify-native-library-as-connection-property.adoc