Subject Re: [firebird-support] My Firebird experience (was Re: ODBC queries with parameters failing)
Author Mark Rotteveel
On 1-3-2013 14:56, Kurt Fitzner wrote:
> After downloading and plugging in jaybird-2.2.2.jar into the classpath
> for LibreOffice, my first challenge was that I kept (and still get when
> I use that jar) an error that "the driver class
> 'org.firebirdsql.jdbc.FBDriver' could not be loaded." This was actually
> the one biggest issue. The documentation suggests that
> jaybird-2.2.2.jar should have the "JDBC driver, the JCA connection
> manager, the Services API and event management classes" with the full
> driver having the "[s]ame as above but also the connection pooling
> classes".

The Jaybird 2.1 programmers manual doesn't explicitly list the exact
libraries of the runtime dependencies (it just says: "Jaybird driver has
compile-time and run-time dependencies to JCA 1.0, JTA 1.0.1, JAAS 1.0
and JDBC 2.0 Optional Package.". The JCA 1.0 (now 1.5) is not include in
the JRE, the other dependencies are include in the JRE (since Java 1.4
and/or Java 5). I will update the documentation in a future version to
be more explicit. The Jaybird 2.2.x release notes, section Distribution
package however is more specific on what you need.

If you use jaybird-2.2.2.jar, then you also need to include
lib/connector-api-1.5.jar on the classpath. If you use Jaybird in an
application server you would just need to include jaybird-2.2.2.jar as
the connector-api is a so-called 'provided' dependency. IIRC some
application servers - as a security measure - will even refuse to load a
JAR file that includes classes in the javax.resource package. The
jaybird-full-2.2.2.jar includes the classes of this required dependency.

> So I figured the first jar was what was normally used, and
> the other one used when connection pooling was also needed. And since
> I knew that there were complications to getting the driver to work for
> embedded, so I didn't try the other jar for quite some time, figuring I
> had made a mistake somewhere else. I set the FIREBIRD environment
> variable, I set the PATH for where I dropped the DLL, I fussed with the
> naming of the embedded server DLL, since its instructions said I might
> have to call it fbclient.dll or gds32.dll. In the end, though, it
> worked when I finally switched from jaybird-2.2.2.jar to
> jaybird-full-2.2.2.jar.

The Jaybird embedded protocol specifically loads fbembed.dll or
libfbembed.so, so you don't need to (nor even should) rename the libraries.

> All the setup required for this, maybe it's still common in Unix land,
> but manually installing an embedded server and setting environment
> variables is not something I can ask the end users I want to distribute
> my database to to do. And dropping random DLLs "somewhere in your
> path" is something that no Windows user should be forced to do any
> more. Especially on 64 bit systems, this can be dangerous. You don't
> want to drop a 32-bit DLL into a directory reserved for 64 bit system
> libraries, for example. End users should never have to manually copy
> libraries around. Anything executable should always be put in place by
> an installer so it can be removed with an uninstaller.

Jaybird is a library that is more geared towards being used/included as
part of the development of a Java application, so having an installer
for it doesn't make sense. And for most cases where you would use
Jaybird as 'just a driver' even then there is no 'one size fits all'
installer possible.

And - most of the time - developers will use the pure java wire protocol
and don't even bother about those native dependencies as they don't need
those. To be blunt: the embedded/native protocol isn't the primary focus
of the driver.

> I'm not developing an "application". Or rather, I suppose I am, but
> it's an end-user sort of thing using Libre/Open Office. I'm not putting
> together an installer - I'm not a VAR. So maybe Firebird just isn't for
> me. It seems to me, though, that a little bit of consolidation would
> make Firebird usable by a much wider audience. I can see no reason why
> the embedded "server" is not included right with the client installer.

The point is that 'embedded' isn't installed: it is usually include in
an application, so including it in the server installer doesn't really
make a lot of sense.

Your specific use case of wanting to run it with LibreOffice deviates
from that general use case of embedded, so things are even trickier.

> Neither can I understand why ODBC and JDBC are also not installed right
> with the client. One stop shopping for all your Firebird client needs.
> No DLLs to copy into paths, no environment variables to set. The added
> size for everything together is trivial. The projects can even be still
> kept separate with the latest release of each tapped for each client
> release.

Might be useful for ODBC, but for Jaybird I don't really see the point:
it is not how - in general - a JDBC driver is used, and even if it was
'installed' with the server, you would still need to configure
LibreOffice to actually recognize it.

I know that MySQL and PostgreSQL installers allow you to install their
JDBC drivers, but that is almost identical to separately downloading the
release zip of the driver and unzipping it: you will still need to
configure any application that can use it; the only difference under
Windows is that you get an uninstall entry that deletes it.

> I did get some funny behaviour using it. For example, I couldn't use
> the navigation buttons to force the cursor to the very end of the result
> set. But this was largely a non-issue since the general performance was
> too sluggish anyway, so I didn't do much investigation into the causes
> of this. It may be, as you say, because of the problems with
> Libre/OpenOffice that you made the "oo" workaround for.

I will see if I will need to include a separate embedded workaround for
Open/LibreOffice and update the documentation to make it simpler to get
it up and running.

> This is less of a dirty trick, I think, than telling an end user to drop
> the DLL into a random PATH directory,

That is an oversimplification of what I said. In general you would
include the binaries in the application folder, I just added that it
could also look in the path. Simply extracting a native binary and
loading it has several security implications in Java that you need to
account for, especially in a JDBC driver. JDBC drivers are used a lot in
application servers that place additional restrictions on locations that
can be written to and locations and/or library names that are allowed
for loading native binaries.

> and far less than having Firebird
> put databases into "Program Files" which is a huge Windows no-no.

The only database that Firebird puts (and actively uses) in Program
Files is the security2.fdb and you may be right that %ProgramData% is a
more correct location. I'd suggest you file a bug:
http://tracker.firebirdsql.org/browse/CORE

> At
> least when the client cleans up, it can delete the DLL. There's a lot
> of software that drops executable bits into temp folders. Every
> installer program on the planet, for one. Most games, also, for copy
> protection DLLs and even services. This is a common, and generally
> accepted practice in Windows. Better than having end users hand manage
> it. I admit, it's not really very cross-platform.

Jaybird is a library, not a full-blown application. The end-users of
Jaybird in general are developers, not normal end-users. This has its
implications for how Jaybird works and why it doesn't account for some
of the ease-of-use that you might expect from an application.

The crossplatform problem has to do with keeping track of the right
native binaries for the right platform, and creating additional problems
on platforms that aren't compatible with the default binaries. This is
on top of the problem I described earlier with regard to application
servers.

And as I said, most Java developers will use the pure java wire protocol
and don't use embedded (or native), so the focus in development (and
documentation) of Jaybird isn't on the native and embedded protocols.

> Does Jaybird
> automatically look in the directory where the jar is for the DLLs it
> needs? I didn't try this myself, because the documentation I read
> seemed to indicate it had to be on the path, and I was trying to
> diagnose the problem with the driver class not loading at the time.

It doesn't load the native binaries from the directory of the JAR, it
leaves loading direct native dependency (libjaybird22.so /
jaybird22.dll) to standard Java method of loading libraries. This uses
the java.library.path system property to locate the binary, for the
additional dependencies loaded by the native library it uses a different
mechanism (I think it loads files in the same folder as libjaybird22.so
/ jaybird22.dll, followed by the PATH). For LibreOffice you would need
to put java.library.path in the JVM parameters (as
-Djava.library.path=<folder>[;<folder>]* ).

Mark
--
Mark Rotteveel