Jaybird 6.0.0-beta-1 is still in development, and intended for testing and evaluation purposes. We do not recommend this version for use in production environments. If you come across any issues when using this version, please report them on https://github.com/FirebirdSQL/jaybird/issues. |
1. Jaybird 6.0.x changelog
Changes per Jaybird 6 release. See also What’s new in Jaybird 6. For known issues, consult Known issues.
2. Known issues
-
Using a native connection with a Firebird 3.0 or higher client library to a Firebird 2.5 or older server may be slow to connect.
Possible workarounds:
-
Use a native URL with the Firebird INET4 protocol (e.g. for
DriverManager
jdbc:firebird:native:inet4://<serverName>[:<portNumber>/<databaseName>
). -
Use the IPv4 address instead of the host name in the connection string
-
Use a Firebird 2.5 or earlier
fbclient
.
This is caused by firebird#4971
-
3. Support
If you need support with Jaybird, join the Firebird-Java Google Group and mailing list. You can subscribe by sending an email to [email protected].
Looking for professional support of Jaybird? Jaybird is now part of the Tidelift subscription.
See also Where to get help
4. General Notes
Jaybird is a JDBC driver suite to connect to Firebird database servers from Java and other Java Virtual Machine (JVM) languages.
This driver does not work on Android, because it uses classes and features not available in Android.
4.1. About this version
Jaybird 6 is an incremental change from Jaybird 5.
The major changes and new features in Jaybird 6 are:
-
Minimum supported Java version is Java 17.
See Java support for more information. -
Minimum supported Firebird version is Firebird 3.0.
See Firebird support for more information. -
The pure Java protocol — by default — no longer connects to Firebird 2.5 and older, as those versions are not supported.
See Pure Java will not connect to unsupported Firebird versions by default for more information. -
The native and embedded protocols have been moved to a separate artifact,
jaybird-native
.
See NATIVE and EMBEDDED support moved to a separate artifact for more information. -
… and Other fixes and changes
Upgrading from Jaybird 5 should be straightforward, but please make sure to read Compatibility changes before using Jaybird 6. If you’re using Jaybird with the native or embedded connections, you will need to make some additional changes. See also Upgrading from Jaybird 5 to Jaybird 6.
Bug reports about undocumented changes in behavior are appreciated. Feedback can be sent to the Firebird-java mailing list or reported on the issue tracker https://github.com/FirebirdSQL/jaybird/issues.
4.2. Supported Firebird versions
Jaybird 6.0.0-beta-1 was tested against Firebird 3.0.12, Firebird 4.0.5, Firebird 5.0.1 and a recent snapshot of Firebird 6.0, but should also support other Firebird versions from 3.0 and up. Firebird 2.5 and older are not supported.
Jaybird 6 will — by default — not connect to Firebird 2.5 or older. See also Pure Java will not connect to unsupported Firebird versions by default.
This driver does not support InterBase.
4.3. Supported Java versions
Jaybird 6 supports Java 17 and higher (JDBC 4.3). Support for earlier Java versions has been dropped.
Given the limited support period for Java 9 and higher versions, we limit support to Java 17, the most recent LTS version after Java 17, and the latest Java release. Currently, that means we support Java 17, Java 21, and Java 23.
Jaybird 5 will serve as a “long-term support” version for Java 8 and 11, with maintenance releases at least until the release of Jaybird 7. |
Jaybird 6 provides libraries compiled for Java 17.
Jaybird 6 is modularized. The available modules are:
org.firebirdsql.jaybird
-
main Jaybird driver (
jaybird-6.0.0-beta-1.jar
) org.firebirdsql.jaybird.chacha64
-
ChaCha64 wire encryption implementation (
chacha64-plugin-6.0.0-beta-1.jar
) org.firebirdsql.jna
-
native and embedded protocol implementation using JNA (
jaybird-native-6.0.0-beta-1.jar
)
See also Java support in What’s new in Jaybird 6.
5. Getting Jaybird 6
5.1. Jaybird 6.0.0-beta-1
5.1.1. Maven
Jaybird 6.0.0-beta-1 is available on Maven Central.
groupId |
|
artifactId |
|
version |
|
For example:
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird</artifactId>
<version>6.0.0-beta-1</version>
</dependency>
If you want to use Type 2 support (native or embedded), you need to explicitly add jaybird-native
as a dependency:
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird-native</artifactId>
<version>6.0.0-beta-1</version>
</dependency>
For Windows and Linux, you can add the org.firebirdsql.jdbc:fbclient
dependency on your classpath to provide the native libraries for the native
protocol.
Be aware that this dependency does not support embedded
.
See also Type 2 (native) and embedded driver.
To enable the “ChaCha64” wire encryption support for pure Java connections, also add:
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>chacha64-plugin</artifactId>
<version>6.0.0-beta-1</version>
</dependency>
5.2. Gradle
See also Maven.
Examples:
implementation 'org.firebirdsql.jdbc:jaybird:6.0.0-beta-1'
implementation 'org.firebirdsql.jdbc:jaybird-native:6.0.0-beta-1'
implementation 'org.firebirdsql.jdbc:chacha64-plugin:6.0.0-beta-1'
5.2.1. Download
You can download the release of Jaybird from https://firebirdsql.org/en/jdbc-driver/
At minimum Jaybird 6 requires jaybird-6.0.0-beta-1.jar
.
For native or embedded support, also add jaybird-native-6.0.0-beta-1.jar
and jna-jpms-5.15.0.jar
on your classpath or modulepath.
See also Type 2 (native) and embedded driver.
For “ChaCha64” wire-encryption support with pure Java connections, also add chacha64-plugin-6.0.0-beta-1.jar
and bcprov-jdk18on-1.78.1.jar
.
6. Upgrading from Jaybird 5 to Jaybird 6
Please make sure to read Compatibility changes before upgrading to Jaybird 6.
6.1. Maven
Change the version of the dependency to 6.0.0-beta-1
.
If you’re using the artifact id jaybird-jdkXX
, change it to jaybird
.
When your Jaybird dependency defines the exclusion for javax.resource:connector-api
(see example below), you can remove it as Jaybird no longer has a dependency on connector-api
.
<exclusions>
<exclusion>
<groupId>javax.resource</groupId>
<artifactId>connector-api</artifactId>
</exclusion>
</exclusions>
For more detailed instructions, see also the information on Maven in Getting Jaybird 6.
If you use native or embedded, you now need to explicitly add jaybird-native
as a dependency:
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird-native</artifactId>
<version>6.0.0-beta-1</version>
</dependency>
If you use native or embedded, make sure to update your JNA dependency to version 5.15.0
and artifact id jna-jpms
, or remove it altogether as the dependencies will now be pulled in through the jaybird-native
artifact.
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-jpms</artifactId>
<version>5.15.0</version>
</dependency>
Previous versions used |
6.2. Manual install
If you manage your dependencies manually, you need to do the following:
-
Replace the Jaybird 5 library with the Jaybird 6 version
-
jaybird-5.0.x.<java>.jar
withjaybird-6.0.0-beta-1.jar
-
-
If you use the NATIVE or EMBEDDED protocols, add the following JARs to the classpath or modulepath
-
jaybird-native-6.0.0-beta-1.jar
-
jna-jpms-5.15.0.jar
from thelib
directory of the distribution zipIf you have an older version of JNA or a
jna-5.15.0
instead ofjna-jpms-5.15.0
, make sure to remove and replace it withjna-jpms
.
-
-
To enable “ChaCha64” wire encryption support add the following JARs to the classpath or modulepath
-
chacha64-plugin-6.0.0-beta-1.jar
-
bcprov-jdk18on-1.78.1.jar
from thelib
directory of the distribution zip
-
6.3. Gotcha’s
If you find a problem while upgrading, or other bugs, please report it on https://github.com/FirebirdSQL/jaybird/issues.
For known issues, consult Known issues.
7. What’s new in Jaybird 6
For a full list of changes, see Milestone “v6-initial”.
7.1. Changes in version numbering
The minimum supported Java version of Jaybird 6 is Java 17. Our expectation is that Java version specific artifacts are no longer needed. As a consequence, the Java version has been dropped from the version number. The full version and naming convention is documented in jdp-2023-01: Version Number and Naming Scheme
As a result of these new naming conventions, the following has changed:
-
Maven version:
6.0.0
(was5.0.0.java8
) -
Distribution zip:
jaybird-6.0.0.zip
(wasjaybird-5.0.0.java8.zip
) -
Jaybird:
jaybird-6.0.0.jar
(wasjaybird-5.0.0.java8.jar
) -
Jaybird sources:
jaybird-6.0.0-sources.jar
(wasjaybird-5.0.0.java8-sources.jar
) -
Jaybird javadoc:
jaybird-6.0.0-javadoc.jar
(wasjaybird-5.0.0.java8-javadoc.jar
)
Furthermore, the client name reported to Firebird is now Jaybird jaybird-6.0.0
(was: Jaybird jaybird-5.0.0.java8
).
7.2. Java support
7.2.1. Java versions before 17 no longer supported
Support of Java versions before Java 17 was dropped.
See also jdp-2022-03: Java 17 minimum version
7.2.2. Java 17 and higher
Jaybird 6 supports Java 17 and higher (JDBC 4.3). Most of the JDBC 4.3 features have been implemented (in as far as they are supported by Firebird).
Given the limited support period for Java 17 and higher versions, not all Java releases are formally supported, see Supported Java versions for details.
7.3. Firebird support
Support for Firebird 2.5 has been dropped. See also Support for Firebird 2.5 dropped.
Jaybird 6 supports Firebird 3.0, Firebird 4.0, and Firebird 5.0, and provides tentative support for Firebird 6.0.
Jaybird 6 will — by default — not connect to unsupported versions (that is, Firebird 2.5 or older). See also Pure Java will not connect to unsupported Firebird versions by default.
7.4. Pure Java will not connect to unsupported Firebird versions by default
The pure Java protocol will by default no longer try the wire protocol versions of unsupported Firebird versions.
This means that — by default — only protocol version 13 (Firebird 3.0) — 18 (Firebird 5.0) are tried.
As a result, attempts to connect to Firebird 2.5 or earlier will result in error “connection rejected by remote interface” (335544421
or isc_connect_reject
).
The connection property enableProtocol
can enable unsupported protocols, assuming a suitable protocol implementation is available on the classpath.
This connection property can have the following values:
-
A comma-separated list of additional protocol versions to try (e.g.
"11,12"
). The listed versions are tried in addition to the supported protocol versions. Non-integer values or unknown protocol versions are silently ignored.It is possible to use the “masked” protocol version (e.g.
"32780"
for protocol version 12). However, we recommend using the unmasked version (e.g."12"
for protocol version 12). -
"*"
— enable all available protocol versions -
null
or empty string (""
) — default behaviour, only use supported protocols
A different default value of enableProtocol
can be set using the system property org.firebirdsql.jdbc.defaultEnableProtocol
.
This system property is checked each time a connection configuration is created, so it can be changed at runtime.
If you use a Jaybird DataSource
implementation, it uses the value at the time the DataSource
is created;
if you use DriverManager
— this can include third-party data sources, it uses the value at the time the connection is created.
Given these protocol versions and their Firebird versions are not supported, there is no guarantee that the driver will function correctly when an unsupported protocol is enabled. Especially things like database metadata could use features that are not supported by older Firebird versions. We recommend upgrading your Firebird version, or downgrading to a Jaybird version which still supports your Firebird version. For maximum compatibility, it is recommended to either use Unsupported protocol versions may be removed in future major releases of Jaybird. |
Firebird version | Maximum protocol |
---|---|
1.0 — 2.0 |
10 |
2.1 |
11 |
2.5 |
12 |
3.0 |
|
4.0 |
16[3] |
5.0 |
18 |
7.5. NATIVE and EMBEDDED support moved to a separate artifact
The NATIVE (JDBC URL prefix jdbc:firebird[sql]:native:
) and EMBEDDED (JDBC URL prefix jdbc:firebird[sql]:embedded:
) protocol implementations have been moved to a separate artifact, org.firebirdsql.jdbc:jaybird-native
.
If you use native or embedded connections using Jaybird, you will need to explicitly add the appropriate Maven dependency (or jaybird-native-6.0.0-beta-1.jar
and jna-jpms-5.15.0.jar
) to your classpath.
See also Getting Jaybird 6.
7.6. OOREMOTE (OpenOffice/LibreOffice protocol) removed
The OOREMOTE protocol (JDBC URL prefix jdbc:firebird[sql]:oo:
) has been removed in Jaybird 6.
The recommended replacement is to use LibreOffice and the builtin “Firebird External” connection option in LibreOffice Base, instead of the “JDBC” option with Jaybird on the classpath of LibreOffice.
7.7. Modularization of Jaybird
Jaybird now uses real Java modules.
The available modules are:
org.firebirdsql.jaybird
-
main Jaybird driver (
jaybird-6.0.0-beta-1.jar
) org.firebirdsql.jaybird.chacha64
-
ChaCha64 wire encryption implementation (
chacha64-plugin-6.0.0-beta-1.jar
) org.firebirdsql.jna
-
native and embedded protocol implementation using JNA (
jaybird-native-6.0.0-beta-1.jar
)
We’ve tried to be liberal with exporting packages from Jaybird, but we have decided not to export some packages because we think they shouldn’t normally be accessed by users of Jaybird.
If you run into problems with packages not being exported, please report this on firebird-java or on https://github.com/FirebirdSQL/jaybird/issues.
Please include an explanation why you need to access a specific package.
As a workaround, you can also add exports yourself with the --add-exports
commandline option of java
and javac
and the Add-Exports
manifest entry of your application (similar options exist for opens).
When the Jaybird JAR files are on the classpath, they should behave as before. For modular applications, once added to the modulepath instead of the classpath, they will behave in a more restricted fashion.
If you use Jaybird only as a JDBC driver (through java.sql.DriverManager
), having the driver on the modulepath and having requires java.sql
in the module-info.java
of your application should be sufficient.
If your code uses classes and other types from Jaybird, you will also need to add requires org.firebirdsql.jaybird
.
The ChaCha64 plugin, org.firebirdsql.jaybird.chacha64
, will just need to be present on the modulepath to be loaded.
The same goes for the native protocol module, org.firebirdsql.jna
, but we recommend you only add it to the modulepath if you actually need native or embedded access.
You also need to replace any jna-<version>.jar
with jna-jpms-5.15.0.jar
(the modular variant of JNA).
If you use org.firebirdsql.jna
to implement a Firebird embedded provider, you’ll need to add requires org.firebirdsql.jna
and an appropriate provides org.firebirdsql.jna.embedded.spi.FirebirdEmbeddedProvider with <classname>
in your module-info.java
.
For compatibility with use on the classpath, it is recommended to also provide the META-INF/services/org.firebirdsql.jna.embedded.spi.FirebirdEmbeddedProvider
file.
For more information, see also jdp-2023-13: Modularization of Jaybird.
7.8. Connection property createDatabaseIfNotExist
The Boolean connection property createDatabaseIfNotExist
instructs Jaybird to attempt to create the database if it does not exist yet.
This property can be used in the JDBC URL, in the Properties
object passed to DriverManager
, and can be set on data sources.
Although Jaybird already allowed you to create databases using org.firebirdsql.management.FBManager
, this is not always accessible, for example in tools or libraries that only expose or use the JDBC API.
This new property provides an alternative way to create databases.
Jaybird allows you to set or override connection properties specifically for creating the database by suffixing the property name with @create
(case-sensitive).
This can be used to set configuration properties that are only relevant for creating the database, or — for example — to use a different user or role for creating the database than used for normal connections.
As an example:
String jdbcUrl = "jdbc:firebird://localhost/exampledb" + "?createDatabaseIfNotExist=true&" + "user@create=sysdba&password@create=masterkey"; try (Connection connection = DriverManager.getConnection( jdbcUrl, "normaluser", "password")) { // ... }
If the database already exists, the connection will be made with user normaluser
, but if the database does not exist, the database and the connection will be created with user sysdba
.
The errors Firebird returns do not make it possible to determine definitively if the database does not exist, or if there is another reason that the connection failed. Jaybird applies some simple rules to exclude some classes of errors, and not attempt to create a database in those cases. If you find cases where you think Jaybird should not — or on the contrary, should — attempt to create a database, please report them on https://github.com/FirebirdSQL/jaybird/issues. |
For more information, see also jdp-2024-02: Create database through JDBC URL.
7.9. Report actual process ID (pid)
The pure Java implementation will now report the actual process ID (pid) in connection property isc_dpb_process_id
.
The native implementation already did this.
For pure Java connections, the reported process ID can be overridden using the connection property processId
or the system property org.firebirdsql.jdbc.pid
.
This feature is retained for backwards compatibility.
When a SecurityManager
is installed, the entire call-chain needs to have the RuntimePermission("manageProcess")
to obtain the process ID in pure Java connections.
If this permission check fails, Jaybird will silently ignore it and not set the isc_dpb_process_id
based on the actual process ID.
7.10. Logging facade removed
The logging facade from package org.firebirdsql.logging
has been removed, and is replaced by the Java Platform Logging API (JEP 264).
The Java Platform Logging API by default logs to java.util.logging
, but it is possible to plug in different logging platforms.
For example, Log4j provides the log4j-jpl
dependency which will replace the default binding to java.util.logging
with one to Log4j.
With this change, Jaybird no longer provides an option to specify a custom logger implementation, so the system property org.firebirdsql.jdbc.loggerImplementation
is no longer supported.
If you need a custom logger, you will need to implement java.lang.System.Logger
and java.lang.System.LogFinder
and provide the necessary service loader definition (see the Java documentation for details).
The system properties org.firebirdsql.jdbc.forceConsoleLogger
and org.firebirdsql.jdbc.disableLogging
are also no longer supported.
Equivalent behaviour is achieved by configuring the active logging library.
7.11. Support for ChaCha64 wire encryption
Support for the “ChaCha64” wire encryption — introduced in Firebird 4.0.1 — was added for the PURE_JAVA
protocol.
Given this requires a dependency on the Bouncy Castle provider (bcprov-jdk18on
), the plugin is made available as a separate artifact: org.firebirdsql.jdbc:chacha64-plugin
on Maven or chacha64-plugin-6.0.0-beta-1.jar
in the distribution zip.
When deploying manually, please make sure to also include the bcprov-jdk18on-1.78.1.jar
from the lib
directory of the distribution zip on the classpath.
As part of this change, Jaybird is now capable of loading EncryptionPluginSpi
instances using the service loader mechanism.
The API of EncryptionPluginSpi
and EncryptionPlugin
and other classes and interfaces in package org.firebirdsql.gds.ng.wire.crypt
should still be considered unstable and internal API, so use it at your own risk to implement your own plugins.
If you want to use it for implementing your own encryption plugins, let us know on firebird-java.
We can then look at stabilizing the API and considering it formally a public API.
See also jdp-2023-06: ChaCha64 Support
7.12. Opt-in feature for package information in DatabaseMetaData
Firebird 3.0 added packages, which can contain stored procedures and functions. The JDBC API does not provide a standard way of accessing information about packages, or the routines defined in packages. Instead of adding additional Jaybird-specific metadata methods, we’ve added an “opt-in” feature that provides access through normal metadata methods, using the “catalog” to report packages.
This feature can be enabled by setting the connection property useCatalogAsPackage
to true
.
When this connection property is enabled, the DatabaseMetaData
of that connection will have the following changes in behaviour:
-
getCatalogs()
lists packages, with package names inTABLE_CAT
. -
getFunctions
,getFunctionColumns
,getProcedures
, andgetProcedureColumns
include information on procedures or functions in packages-
Columns
FUNCTION_CAT
/PROCEDURE_CAT
will report:-
For packaged procedures and functions — the package name
-
For normal (non-package) procedures and functions — an empty string instead of
null
(because of the following rule)
-
-
If parameter
catalog
is""
(empty string), only normal stored procedures or stored functions are reported. -
If parameter
catalog
isnull
, both packaged and normal stored procedures or stored functions are reported. -
For other values of parameter
catalog
, these metadata methods will only return procedures, functions, or their columns of the specified package (exact match, case-sensitive; not aLIKE
pattern) -
For normal (non-package) procedures and functions, the
SPECIFIC_NAME
column will be the unquoted function or procedure name (same as whenuseCatalogAsPackage
is not enabled), and for packaged procedures and functions, it will bequoted-package-name + '.' + quoted-routine-name
(e.g."SOME_PACKAGE"."SOME_FUNCTION"
)
-
-
getCatalogSeparator()
returns"."
(string with period). -
getCatalogTerm()
returns"PACKAGE"
. -
isCatalogAtStart()
returnstrue
. -
getMaxCatalogNameLength()
returns 31 or 63 depending on the max identifier length of the database. -
supportsCatalogsInDataManipulation()
returnstrue
(i.e. access selectable stored procedures and functions from packages). -
supportsCatalogsInProcedureCalls()
returnstrue
. -
The other
supportsCatalogsIntype()
methods continue to returnfalse
. -
Other metadata methods with a
catalog
parameter continue to ignore it, just like they do whenuseCatalogAsPackage
is disabled.
The useCatalogAsPackage
connection property does not result in any other behaviour.
Keep in mind, that this is non-standard behaviour, and standard JDBC tools or libraries may not work correctly when this property is enabled. This feature may be discontinued and removed in the future if Jaybird needs to implement “real” catalogs (e.g. because Firebird started supporting catalogs).
See also jdp-2023-08: Use Catalog as Package
7.13. Asynchronous fetching
For pure Java connections, non-holdable forward-only result sets now perform asynchronous fetches. Asynchronous fetches are implemented for protocol implementation version 11 and higher (i.e. Firebird 2.1 or higher), but are formally only supported for protocol version 13 and higher (i.e. Firebird 3.0 or higher).
In normal usage of a result set, the first fetch will be a normal synchronous fetch. If certain conditions are met, subsequent fetches will be performed asynchronously.
The conditions for using asynchronous fetch are considered an implementation detail and may change in point releases. In Jaybird 6.0.0, the conditions to enable asynchronous fetching are:
-
The result set has type
FORWARD_ONLY
. -
The result set does not have a cursor name set.
-
Any synchronous fetch on the statement cursor retrieved at least 15 rows. Be aware that the server may return fewer rows than the configured fetch size (default is 400), depending on Firebird version, row size and other factors.
When the asynchronous fetch is triggered is also an implementation detail and may change in point releases. In Jaybird 6.0.0, the conditions to perform an asynchronous fetch are:
-
Size of the row buffer is equal to the “low-water mark”.
This “low-water mark” is calculated as ~33% of the maximum number of rows returned by previous fetches, with a minimum of 10 rows.
As a consequence of this condition, reducing the fetch size equal to or less than the “low-water mark” may cause asynchronous fetches to stop being triggered, as the buffer size may remain smaller than this “low-water mark” (this effect may be reduced if there is other activity on the connection after the asynchronous fetch was performed). In that case a synchronous fetch is triggered when the buffer is empty.
-
Fetch size at time of async fetch is larger than 1. This may be the configured fetch size, or the fetch size derived taking into account the configured maximum row count.
Native connections do not support this type of asynchronous fetching, but fbclient
itself provides a different form of internal asynchronous fetching for native connections.
7.14. Blob performance improvements
7.14.1. Reading blobs
Performance of reading blobs has been improved, especially when using getBytes
on ResultSet
or Blob
, or getString
on ResultSet
or Clob
, or reading from a blob input stream with read(byte[], int, int)
and similar methods with a byte array and requested length greater than 50% of the configured blobBufferSize
.
Testing on a local network (Wi-Fi) shows an increase in throughput of roughly 50-100% for reading large blobs with the default blobBufferSize
of 16384.
These throughput improvements were only realised in the pure Java protocol, because there we had the opportunity to avoid all additional allocations by writing directly from the network stream into the destination byte array, and this allows us to ignore the configured blobBufferSize
and use up to the maximum request size of 65535 bytes instead.
This is not possible for the JNA-based protocols (native/embedded), as the implementation requires a direct byte buffer to bridge to the native API, and thus we can’t ignore the blobBufferSize
.
We were able to realise some other optimizations (in both pure Java and JNA), by avoiding allocation of a number of intermediate objects, but this has only marginal effects on the throughput.
7.14.2. Writing blobs
Performance of writing blobs was improved, especially when using setBytes
on PreparedStatement
, ResultSet
or Blob
, or setString
on PreparedStatement
, ResultSet
or Clob
, or writing to a blob output stream with write(byte[], int, int)
and similar methods with a byte array larger than the configured blobBufferSize
.
A smaller improvement was made when using arrays larger than 50% of the blobBufferSize
.
Testing on a local network (Wi-Fi) shows an increase in throughput of roughly 300-400% for writing large blobs with the default blobBufferSize
of 16384.
The improvement is not available for all methods of writing blobs, for example using ResultSet.setBinaryStream
does not see this improvement, as it relies on the blobBufferSize
for transferring the blob content.
Most of these throughput improvements were only realised in the pure Java protocol, because there we had the opportunity to avoid all additional allocations by writing directly from the source byte array to the network stream, and this allows us to ignore the configured blobBufferSize
and use up to the maximum segment size of 65535 bytes instead.
For the JNA-based protocols (native/embedded) a smaller throughput improvement was realised, by using the maximum segment size for the first roundtrip if the array write used offset 0
.
If the length is larger than the maximum segment size, or if the offset is non-zero, we need to allocate a buffer (for subsequent segments in case offset is 0
), and thus cannot ignore the blobBufferSize
.
Similar to the improvements for reading, we were also able to realise some other optimizations (in both pure Java and JNA), by avoiding allocation of a number of intermediate objects, but this has only marginal effects on the throughput.
7.14.3. Minimum blobBufferSize
512 bytes
As part of the performance improvements, a minimum blobBufferSize
of 512 bytes was introduced.
Configuring values less than 512 will be ignored and use 512 instead.
7.14.4. Maximum segment size raised
For connections to Firebird 3.0 and higher, the maximum segment size was raised from 32765 to 65535 bytes to match the maximum segment size supported by Firebird.
The maximum segment size is the maximum size for sending segments (put) to the server. Due to protocol limitations, retrieving segments from the server (get) is two bytes (or multiples of two bytes) shorter[4].
7.14.5. Effectiveness of blobBufferSize
larger than maximum segment size
Previously, when reading blobs, a blobBufferSize
larger than the maximum segment size was effectively ignored.
Now, when reading through an input stream, a blobBufferSize
larger than the maximum segment size can be used.
Jaybird will use one or more roundtrips to fill the buffer.
To avoid inefficient fetches, a minimum of 90% of the buffer size will be filled up to the blobBufferSize
.
This change is not likely to improve performance, but it may allow for optimizations when reading or transferring data in large chunks.
In general, setting the blobBufferSize
larger than 65535 bytes will likely not improve performance.
7.14.6. Internal API changes for FbBlob
Two new methods were added to FbBlob
:
int get(byte[] b, int off, int len)
-
populates the array
b
, starting atoff
, for the requestedlen
bytes from the blob, and returns the actual number of bytes read. This method will read untillen
bytes have been read, and only return less thanlen
when end-of-blob was reached. int get(byte[] b, int off, int len, float minFillFactor)
-
populates the array
b
, starting atoff
, for at leastminFillFactor
*len
bytes (up tolen
bytes) from the blob, and returns the actual number of bytes read. void put(byte[] b, int off, int len)
-
sends data from array
b
to the blob, starting atoff
, for the requestedlen
bytes.
The documentation of method FbBlob.putSegment(byte[])
contradicted itself, by requiring implementations to batch larger arrays, but also requiring them to throw an exception for larger arrays, and the actual implementations provided by Jaybird threw an exception.
This contradiction has been removed, and the implementations will now send arrays longer than the maximum segment size to the server in multiple put requests.
7.15. Support for executing transaction management statements
In Jaybird 5 and earlier, it was not possible to execute the transaction management statements COMMIT
, ROLLBACK
(without RETAIN
or a savepoint) and SET TRANSACTION
.
For COMMIT
and ROLLBACK
it would seem to work, but subsequent use of the connection would then break because the connection assumed it still had an active transaction.
Formally, the JDBC specification says — paraphrased — that if something can be done through the JDBC API, that those API methods should be used; you should not use equivalent statements. However, from a perspective of flexibility, and for example for executing scripts, it can be useful to be able to execute those statements.
Jaybird now optionally allows you to execute COMMIT [WORK]
, ROLLBACK [WORK]
and SET TRANSACTION […]
.
By default, Jaybird 6 explicitly rejects attempts to execute those statements, instead of the half-working/half-broken situation of previous versions.
To allow execution of COMMIT [WORK]
, ROLLBACK [WORK]
and SET TRANSACTION […]
, the connection property allowTxStmts
needs to be set to true
.
This can be done using a JDBC connection property allowTxStmts
, or setAllowTxStmts(boolean)
on DataSource
instances.
Just because you can, doesn’t mean you should use this. For code solutions, you should use the normal methods in the JDBC API whenever possible. Only use this solution for scripts, or in case it is cumbersome or not possible to access the Jaybird extensions to the JDBC API to control the transaction configuration. |
In the implementation, the use of COMMIT
and ROLLBACK
will not be executed as statements on the server, but instead call Connection.commit()
and Connection.rollback()
.
The SET TRANSACTION
statement — if allowed — is executed with execute immediate, and not through a statement handle.
Contrary to its name, and the SQL standard behaviour, Firebird’s |
Enabling this feature can also make it easier to use the table reservation feature, compared to FirebirdConnection.setTransactionParameters(TransactionParameterBuffer)
or FirebirdConnection.setTransactionParameters(int, TransactionParameterBuffer)
, which requires access to the Jaybird API interfaces.
This feature has the following limitations:
-
Transaction management statements cannot be executed when auto-commit is enabled, or if the connection is participating in a distributed transaction. This is the same behaviour as implemented for
Connection.commit()
andConnection.rollback()
. -
Executing
COMMIT
orROLLBACK
— when auto-commit is disabled — is silently ignored if there is no active transaction. This is the same behaviour as implemented forConnection.commit()
andConnection.rollback()
. -
SET TRANSACTION
cannot be executed if there is an active transaction. In other words, you will need to callConnection.commit()
or executeCOMMIT
(or roll back) before you can start a new transaction this way. -
Transaction management statements are not supported by
Statement.addBatch(String)
,PreparedStatement.addBatch()
, andConnection.prepareCall(…)
.
For more information, see also jdp-2024-01: Explicit support for transaction statements.
7.16. Configurable buffer sizes for the wire protocol
The sizes of a number of buffers used in the wire protocol were increased from 512 bytes to 8192 bytes. This specifically concerns:
-
wire compression — deflate (compression)
-
wire compression — inflate (decompression)
-
wire encryption — decrypt
There is no such buffer for the reverse (encryption), as this is already handled by the general output buffer.
This change might not be desirable in all situations as it increases the total amount of memory per connection, or there can be reasons to further increase these buffers. To address this, we have added system properties to configure a number of buffers which were previously not configurable:
org.firebirdsql.wire.deflateBufferSize
-
Buffer size in bytes for deflate (compression). Has a minimum size of 512 and a default value of 8192.
org.firebirdsql.wire.inflateBufferSize
-
Buffer size in bytes for inflate (decompression). Has a minimum size of 512 and a default value of 8192.
org.firebirdsql.wire.decryptBufferSize
-
Buffer size in bytes for decryption. Has a minimum size of 512 and a default value 8192.
As the decryption input buffer determines the size of the decryption output buffer, the actual allocation is up to twice the specified value.
org.firebirdsql.wire.inputBufferSize
-
Buffer size in bytes for reading data from the socket. Has a minimum size of 1024 and a default value of 16384.
This property should not be confused with the socket buffer size (configurable with the
socketBufferSize
connection property). Setting this value higher thansocketBufferSize
is unlikely to have any benefits. org.firebirdsql.wire.outputBufferSize
-
Buffer size in bytes for writing data. Has a minimum size of 1024 and a default value of 32767.
This property should not be confused with the socket buffer size (configurable with the
socketBufferSize
connection property). Contrary to the input buffer size, setting it higher thansocketBufferSize
might have performance benefits.
These properties need to be set before Jaybird is loaded and used (e.g. on the commandline with -D<propertyName>=<propertyValue
).
The minimum sizes and default values should be considered an implementation detail and might change in a future major version. The “deflate” and “inflate” buffers are only used when wire compression is enabled. The “decrypt” buffer is only applied when wire encryption is used (the default with Firebird 3.0 and higher). |
The order of buffers for input is as follows:
Jaybird ⇐ [inflate ⇐] [decrypt ⇐] input ⇐ socket
The order of buffers for output is as follows:
Jaybird ⇒ output [⇒ deflate] ⇒ socket
A future version may introduce connection properties to control this per connection.
7.17. Broken connection detection for event manager
The event manager now attempts to detect if the underlying database connection is broken. Once a broken connection is detected, the event manager will attempt to close or forcibly disconnect itself and report itself as not connected.
For proper detection of some types of network problems in a timely manner, it may be necessary to configure the soTimeout
of the event manager before connecting.
When the createFor(Connection)
method has been used, this can be configured through the soTimeout
connection property, or — for pure Java connections only — the setNetworkTimeout
method of the Connection
object.
This detection depends on actual activity, like an event posting a new count, or a new event registration.
7.18. Connection property to specify native library path
A connection property nativeLibraryPath
was added to specify the directory where fbclient
(for native connections), or fbembed
or fbclient
(for embedded connections) can be loaded.
If a file path is used instead of a directory path, the parent directory will be used for the search path.
In other words, it is not possible to use it load a differently named library.
This property comes with a very important caveat: it only works for the first native or embedded connection (to a database or service) made within a JVM. Once any client library is loaded, that library is used for all subsequent native and embedded connections. |
This property is only exposed as a JDBC property.
For data sources, it needs to be set with setProperty(String, String)
or setNonStandardProperty(String)
.
The primary use case for this property is for situations where configuring the system property jna.library.path
is not easy to do (e.g. in third-party applications).
For embedded connections, if there is a valid FirebirdEmbeddedProvider
on the classpath, it will be used instead of the location specified by nativeLibraryPath
.
7.19. Rewritten client info properties support
Client info properties were introduced in JDBC 4.0 and implemented in Jaybird 2.2. This support has been rewritten to remove some limitations and correct some problems with the previous implementation.
The new implementation discerns two types of property names:
-
without context; get/set in
USER_SESSION
context ofRDB$GET/SET_CONTEXT
-
with context, when the name ends in
@USER_SESSION
,@USER_TRANSACTION
or@SYSTEM
; get/set without that suffix in the specified context. Properties with multiple contexts (e.g.property@SYSTEM@USER_SESSION
) are not allowed to prevent ambiguity. Everything else is a property without context.
A property named <name>@USER_SESSION
is handled identical to <name>
.
The “without context” name is preferred and recommended for USER_SESSION
properties, and Connection.getClientInfo()
will use the “without context” name as the key for USER_SESSION
properties.
A property named <name>@USER_TRANSACTION
is set and get as <name>
in context USER_TRANSACTION
.
When a connection is in auto-commit mode, attempts to set or get USER_TRANSACTION
properties are ignored (nothing is stored, and null
is returned without accessing the database).
A property named <name>@SYSTEM
is retrieved as <name>
in the context SYSTEM
.
Properties in the SYSTEM
context are read-only, so they cannot be set.
For Connection.setClientInfo(String, String)
, attempts to set a SYSTEM
property result in a SQLClientInfoException
, for Connection.setClientInfo(Properties)
, SYSTEM
properties are silently ignored.
Attempts to retrieve non-existent properties, even from SYSTEM
will return null
and will not result in an exception.
A connection registers properties known to that specific connection.
By default, only the JDBC-specified properties ApplicationName
, ClientUser
and ClientHostName
(see also below) are known.
A successful get or set of a property will register that property as a known property for the current connection only.
The method Connection.getClientInfo()
will retrieve only known properties (the default properties and those registered for the current connection).
It will not attempt to query or identify other variables registered in any context.
The method Connection.setClientInfo(Properties)
clears (sets to NULL
) known properties in USER_SESSION
and — if not in auto-commit — USER_TRANSACTION
if they are not included in the Properties
object.
DatabaseMetaData.getClientInfoProperties()
reports the JDBC-specified properties only;
it will not report the additional properties registered for the current connection.
The JDBC-specified properties are:
ApplicationName
The name of the application currently utilizing the connection
ClientUser
The name of the user that the application using the connection is performing work for. This may not be the same as the username that was used in establishing the connection.
ClientHostname
The hostname of the computer the application using the connection is running on.
All JDBC-specified properties are get and set in USER_SESSION
.
On get of ApplicationName
, if this property is not currently set in USER_SESSION
, it falls back to get the value from CLIENT_PROCESS@SYSTEM
.
The CLIENT_PROCESS@SYSTEM
value can be specified using the connection property processName
or system property org.firebirdsql.jdbc.processName
.
The ClientUser
and ClientHostname
properties are considered application-specific and have no default value or fallback.
Compared to the previous implementation, the important differences are:
-
Connection.getClientInfo()
now reports properties; the previous implementation always returned an emptyProperties
object. -
Connection.getClientInfo(String)
with a property name without context now queries onlyUSER_SESSION
; the previous implementation queriedUSER_TRANSACTION
, and if not set, fell back to the value fromUSER_SESSION
. To retrieve fromUSER_TRANSACTION
in the new implementation, use<name>@USER_TRANSACTION
. -
Connection.setClientInfo(Properties)
now clears known properties not included in theProperties
object; the previous implementation only set the included properties. -
Successful get or set of a property registers it as known property of the connection and influences behaviour of subsequent calls to
getClientInfo()
andsetClientInfo(Properties)
on that connection -
DatabaseMetaData.getClientInfoProperties
now reports the JDBC-specified properties, and nothing else; the previous implementation always returned an empty result set.
7.20. TIMESTAMP
fields now accept LocalDate
and LocalTime
The JDBC specification does not specify support for LocalDate
and LocalTime
on TIMESTAMP
(without time zone).
However, when we introduced support for the java.time
types, we implemented support for getting LocalDate
and LocalTime
(through getObject
), but did not provide support for setting values of those types (through setObject
) on TIMESTAMP
.
We have now addressed this inconsistency, by also introducing support for setting these types on TIMESTAMP
with the following behaviour:
-
setObject(…, localTime)
sets aLocalDateTime
derived asLocalDate.EPOCH.atTime(localTime)
(i.e. on 1970-01-01) -
setObject(…, localDate)
sets aLocalDateTime
derived aslocalDate.atStartOfDay()
(i.e. at 00:00:00)
7.21. ResultSet
in auto-commit no longer closed after last row
In previous Jaybird versions, iterating over a forward-only result set in auto-commit mode would implicitly close the result set after the last row was fetched — i.e. when next()
returned false
.
This behaviour complied with the JDBC 3.0 requirements, but in JDBC 4.0 this requirement was removed, but still allowed.
In Jaybird 6, this implicit close has been removed.
In auto-commit mode, a result set will now remain open until explicitly closed using ResultSet.close()
, when any statement is executed, when the auto-commit mode is disabled, or by the close of the Statement
or Connection
.
As a result set close is an auto-commit boundary, this change may delay commit of the active transaction until another action on the connection.
If you relied on this implicit close for correctness of your application, you may need to add an explicit call to ResultSet.close()
— e.g. using try-with-resources.
For more information, see also jdp-2024-03: Do not close result set after last row in auto-commit.
7.22. Changes to behaviour of updatable scrollable result sets
Jaybird 5 introduced support for server-side scrollable cursors on Firebird 5.0 and higher in the pure Java protocol.
This can be enabled using the connection property scrollableCursor=SERVER
.
For implementation reasons, updatable server-side scrollable cursors had a different behaviour than the emulated client-side scrollable cursors. These differences are:
-
New rows are inserted at the end of the cursor; in emulated they were inserted immediately before the current row.
-
Deleted rows have an all-
null
marker row; in emulated the row was removed from the cursor. -
The result set reports
true
forrowDeleted()
,rowInserted()
orrowUpdated()
for — respectively — deleted, inserted or updated rows; in emulated these always reportedfalse
.
In Jaybird 6, this new behaviour is now also used for the updatable emulated scrollable cursors. The reason is that having two different sets of behaviours can be confusing, as it makes it impossible to switch between the two without having to account for the behavioural differences (either intentionally, or because you’re connecting with the native or embedded protocol, or to an older version of Firebird).
We’re considering to make server-side scrollable cursors the default in a future Jaybird version (Jaybird 7 or later).
7.23. Other fixes and changes
-
Improvement: Setting oversized strings on
CHAR
orVARCHAR
parameters with character set UTF8 will now throw aDataTruncation
exception onsetString
(and not set a value) instead of aSQLException
with a “string right truncation” error on execute (#396)With this change, the behaviour for UTF8 is now consistent with that of single-byte character sets. For UTF8, the
DataTruncation
reports the transfer size and data size in Unicode codepoints. For other multibyte character sets, theDataTruncation
reports those sizes in bytes. This change is not applied to UNICODE_FSS, as Firebird 3.0 and earlier do not enforce character length limits for this character set, only byte length limits.The
setBytes
method onCHAR
andVARCHAR
parameters only check the byte length limit. -
Improvement: Implemented
java.sql.Connection.abort(Executor)
to forcibly abort a connection (#496)The
java.sql.Connection
is marked closed immediately, after which the executor is used to mark client-side statements and result sets as closed, and then closes the actual physical connection. The close of the physical connection is not a clean close and may result in “connection reset by peer” errors (e.g. error 10054 on Windows, error 104 on Linux) logged infirebird.log
. Active transactions may not be rolled back immediately; this will be delayed until the server detects that the connection was closed. It is possible that some listeners are not informed of the connection, statement or result set close. When a security manager is active, callingabort
requires theSQLPermission
“callAbort”. -
Changed:
DatabaseMetaData.getTypeInfo()
columnFIXED_PREC_SCALE
(column 11) now returnsfalse
for all data types exceptNUMERIC
andDECIMAL
(#551)This was done because of the stated requirement “can it be a money value”. Previously almost all types returned
true
(including — for example —BOOLEAN
andTIMESTAMP
, which are definitely not money types). -
Consistent use of
BigDecimal.valueOf(double)
instead of a combination ofnew BigDecimal(double)
andBigDecimal.valueOf(double)
(#553) -
Switched blob identification in message BLR from
blr_quad
toblr_blob2
(#726) -
Removed
finalize()
methods and — where it made sense — replaced them with use ofCleaner
(#727) -
Fixed:
FBResultSetMetaData.getPrecision
would always estimate the precision ofNUMERIC
orDECIMAL
columns instead of obtaining the actual precision if the column position was 71 or higher (#731)This fix was backported to Jaybird 5.0.5.
-
Optimized the query to retrieve extended field info for
ResultSetMetaData.getPrecision
to only retrieve columns of typeNUMERIC
orDECIMAL
(#732)This improvement was backported to Jaybird 5.0.5.
-
Added methods
List<String> getTypeAliasList()
andList<String> getSupportedProtocolList()
toGDSFactoryPlugin
, and deprecatedString[] getTypeAliases()
andString[] getSupportedProtocols()
for removal in Jaybird 7 or later -
Fixed formatting of
isc_formatted_exception
to not repeat the original parameters of the exception (#749) -
Added aliases
ApplicationName
andapplicationName
for connection propertyprocessName
(#751) -
Fixed: on
CHAR
fields, a too short value could be returned if the string contained one or more codepoints represented by surrogate pairs and the string length inchar
exceeded the maximum string length (#760)We now truncate the returned string if the codepoint count exceeds the maximum string length.
This change was also backported to Jaybird 5.0.3.
-
Improvement: Do not reject attempts to read blob id 0 (#764)
Previously, Jaybird rejected attempts to read blobs with blob id
0
(not on all code paths, for some only when assertions are enabled). Formally, blob id0
is not a valid blob id, but in practice they can occur (e.g. due to bugs, or access components/drivers explicitly setting a blob column to id0
). Other drivers and tools simply send the requests for blob id0
to the server, which then treats it as an empty blob. For consistency, we decided to let Jaybird handle it the same.This change was also backported to Jaybird 5.0.3.
-
Improvement:
Statement.getResultSet
no longer throws aSQLException
with message “Only one result set at a time/statement” if the current result set has already been returned byexecuteQuery
or a previous call togetResultSet
(#762)Repeated calls to
getResultSet
will now return the current result set. As part of this change implementations ofFirebirdStatement.getCurrentResultSet
now simply returnsgetResultSet
, and thegetCurrentResultSet
method has been deprecated for removal in Jaybird 7.This change was also backported to Jaybird 5.0.5.
-
Fixed: The implementation of
Blob.getBytes(long, int)
threw aSQLException
if the remaining bytes of the blob were less than the requested number of bytes (#767)The JDBC API specifies “This
byte
array contains up tolength
consecutive bytes starting at position pos.”, so the implementation was changed to return up tolength
bytes, or the remaining actual blob length, whichever is shorter.The JDBC API does not specify what should happen if the requested position is beyond the end-of-blob. The modified implementation returns an empty array, but given this is unspecified behaviour, we reserve the option to change this in the future to throw an exception instead.
-
Fixed:
CallableStatement.getXXX(String)
could return value from wrong column (#771)This change was also backported to Jaybird 4.0.10 and Jaybird 5.0.3.
-
FBResultSetNotUpdatableException
now extendsSQLNonTransientException
instead ofFBSQLException
. -
Jaybird no longer throws any instances of
FBSQLException
.FBSQLException
has been deprecated for removal in Jaybird 7. -
Fixed: FBRowUpdater incorrectly considers result set with only partial PK updatable (#780)
This change also improves performance of
updateRow()
,insertRow()
,deleteRow()
andrefreshRow()
. The best row identifier orRDB$DB_KEY
were detected each time when callingupdateRow()
,insertRow()
,deleteRow()
, orrefreshRow()
. This has been improved so this detection is done once, and in a way that non-updatable result sets can now be downgraded toCONCUR_READ_ONLY
instead of throwing an exception when performing the modification.This change was backported to Jaybird 5.0.4.
-
Improved detection of (non-)updatable result sets.
If the best row identifier was not matched, but the result set contains
RDB$DB_KEY
, we will now consider the result set updatable. However, if the table in question has a primary key, and the columns missing from the result set are not generated, this may still fail when callingResultSet.insertRow()
. -
The user manager API (
UserManager
/FBUserManager
andUser
/FBUser
in packageorg.firebirdsql.management
) has been deprecated (#782)We do not plan to remove this API at this time, but we recommend that you switch to using the SQL user management statements.
-
Fixed: Use of offset timezone names (e.g.
+05:00
) forsessionTimeZone
would result in a warning being logged, and an incorrect conversion applied (in UTC instead of the offset) when using the legacy time types (#786)This change was also backported to Jaybird 5.0.4.
-
New feature: Added column
JB_PK_INDEX_NAME
to the result set ofDatabaseMetaData.getPrimaryKeys
with the name of the index backing the primary key (#791)Given this is a non-standard extension, it is advisable to retrieve this column by name, not by position.
-
Improvement:
sessionTimeZone
now also accepts the Java offset names (GMT[+-]HH:MM
), which will be automatically converted to the Firebird compatible name ([+-]HH:MM
). -
New feature:
ResultSetMetaData.isAutoIncrement(int)
reportstrue
for identity columns if Jaybird can identify the underlying table and column (#793)This feature was backported to Jaybird 5.0.5.
-
New feature: Boolean connection property
extendedMetadata
(defaulttrue
) to disable querying of extended metadata forgetPrecision(int)
andisAutoIncrement(int)
ofResultSetMetaData
(#795)Disabling extended metadata may improve performance of these
ResultSetMetaData
methods in exchange for estimated precision information ofNUMERIC
andDECIMAL
columns, and not being able to determine the auto-increment status ofINTEGER
,BIGINT
orSMALLINT
columns.This feature was backported to Jaybird 5.0.5.
-
Improvement: The
FILTER_CONDITION
ofDatabaseMetaData.getIndexInfo
is populated for Firebird 5.0 partial indices (#797)This improvement was backported to Jaybird 5.0.5.
-
Improvement: Added column
JB_PK_INDEX_NAME
andJB_FK_INDEX_NAME
to the result set of togetImportedKeys
,getExportedKeys
andgetCrossReference
ofDatabaseMetaData
with the names of the index backing the primary key and foreign key (#798)Given this is a non-standard extension, it is advisable to retrieve these columns by name, not by position.
-
Change:
TYPE_FORWARD_ONLY
is no longer upgraded toTYPE_SCROLL_INSENSITIVE
when requesting holdable result sets explicitly (holdabilityHOLD_CUSORS_OVER_COMMIT
) or implicitly (defaultResultSetHoldable=true
when not specifying holdability) (#802) -
Improvement:
isPoolable()
onPreparedStatement
andCallableStatement
now returns the default oftrue
—Statement
returnsfalse
— as required by JDBC, andsetPoolable
records the value set to be returned byisPoolable
(#803)To be clear, Jaybird does not provide statement pooling. This change is only about returning and recording the poolable information for JDBC compliance, so it can be used by — for example — connection pool implementations that provide statement pooling.
-
The state of
Connection.setReadOnly(boolean)
was not retained after callingConnection.setTransactionIsolation(int)
or other method calls that changed the current transaction parameter buffer (#805) -
Fixed: Exceptions during statement execution did not always complete the statement, which could delay transaction commit in auto-commit mode (#806)
This fix was backported to Jaybird 5.0.6.
-
Fixed:
ResultSet.isBeforeFirst()
andResultSet.isAfterLast()
should always reportfalse
for an empty result set (#808) -
Most public classes in package
org.firebirdsql.jdbc
have been annotated with@InternalApi
to reflect that they are not actually part of the public API of Jaybird.Informally, these classes were already considered internal API, but given they are
public
, we now explicitly and formally document their status for clarity.Where possible, use the standard JDBC interfaces. If you need access to Firebird-specifics, unwrap or cast to the
org.firebirdsql.jdbc.FirebirdXXX
interfaces. Only cast to or otherwise access the concrete classes oforg.firebirdsql.jdbc
if you really have to, and keep in mind that their API — if not defined injava.sql
orFirebirdXXX
interfaces — may change in point releases.If you have a clear use-case that currently requires access to the concrete implementation classes, and you think it should be possible through a public API, please let us know on firebird-java or the https://github.com/FirebirdSQL/jaybird/issues.
-
Improvement: moved methods
getExecutionPlan()
andgetExplainedExcutionPlan()
fromFirebirdPreparedStatement
toFirebirdStatement
, and clarified behaviour.We also fixed a potential
NullPointerException
in the implementation of these methods inPreparedStatement
andCallableStatement
.The methods
getLastExecutionPlan()
andgetLastExplainedExecutionPlan()
which were already defined inFirebirdStatement
now have a default implementation that callgetExecutionPlan()
andgetExplainedExecutionPlan()
. These methods have been deprecated with the advice to use the new getters. For now, we have no plans to remove these methods in a future release. -
Added dependency on
org.jspecify:jspecify
for nullability annotations.We are working on adding nullability information where applicable, but right now annotation of Jaybird is far from complete, and this will generally only be added when we touch a class for other reasons. The addition of these annotations is intended for making it easier for us to reason about the implementation, and get static analysis warnings about possible programming errors. Hopefully it will — in time — provide some benefits for users of Jaybird’s extension interfaces and “internal” APIs.
If a type or its containing package is not annotated, consider return values and parameters of its methods nullable unless stated otherwise in the API documentation.
In practice, this is an optional dependency, but Maven will pull it in by default, as that is recommended by JSpecify. If the JSpecify JAR is not included on the classpath or modulepath, Jaybird will still work.
-
DatabaseMetaData
now reportsResultSet.TYPE_SCROLL_SENSITIVE
as not supported, as it is always downgraded toTYPE_SCROLL_INSENSITIVE
, and thus effectively not supported.This affects the return value of the methods
supportsResultSetType(int)
,supportsResultSetConcurrency(int, int)
,ownUpdatesAreVisible(int)
,ownDeletesAreVisible(int)
,ownInsertsAreVisible(int)
. -
Improvement:
setObject
/updateObject
methods onPreparedStatement
,CallableStatement
andResultSet
with theint scaleOrLength
parameter will now redirect to variants accepting a length ofset/updateBinaryStream
forInputStream
andset/updateCharacterStream
forReader
(#822) -
New feature: Reporting of
SQLWarning
s can be disabled with connection propertyreportSQLWarnings
(supported case-insensitive values:ALL
(default),NONE
) (#825)The default can be overridden globally using system property
org.firebirdsql.jdbc.defaultReportSQLWarnings
.
7.24. Potentially breaking changes
Jaybird 6 contains a number of changes that might break existing applications.
See also Compatibility changes for details.
7.25. Removal of deprecated classes and packages
See Removal of deprecated classes, packages and methods in Compatibility changes for more details.
8. Compatibility changes
Jaybird 6 introduces some changes in compatibility and announces future breaking changes.
The list might not be complete, if you notice a difference in behavior that is not listed, please report it as bug. It might have been a change we forgot to document, but it could just as well be an implementation bug.
8.1. Support for Firebird 2.5 dropped
Jaybird 6 has dropped support for Firebird 2.5 (see also jdp-2021-03: Drop Firebird 2.5 support).
By default, Jaybird 6 will only connect to Firebird 3.0 and higher. See also Unsupported protocol version disabled by default.
If the version 12 protocol (Firebird 2.5) is explicitly enabled, we expect the driver to remain functional, but chances are certain metadata — e.g. DatabaseMetaData
— will break if we use features introduced in newer Firebird versions.
8.2. Unsupported protocol version disabled by default
The wire protocol versions for Firebird 2.5 and earlier are disabled by default to disallow connection for the pure Java protocol.
Attempts to connect to Firebird 2.5 or earlier will result in error “connection rejected by remote interface” (335544421
or isc_connect_reject
).
You can use connection property enableProtocol=*
or — for example — enableProtocol=10,11,12
to re-enable these protocols, or use the native protocol to connect instead.
As these protocols are not supported, it is possible things will break, especially for metadata — e.g. DatabaseMetaData
if we use features introduced in newer Firebird versions.
8.3. Support for Java versions before Java 17 dropped
Jaybird 6 does not support Java versions before Java 17. You will need to upgrade to Java 17 or higher, or remain on Jaybird 5.
Jaybird 5 will serve as a form of “long-term support” for Java 8 and 11, with maintenance releases at least until the release of Jaybird 7.
8.4. Native and embedded require extra artifact
The main jaybird
artifact no longer provides native and embedded support.
Add the jaybird-native
artifact if you use native or embedded (JDBC URL prefix jdbc:firebird[sql]:native:
or jdbc:firebird[sql]:embedded:
).
8.5. Support for jdbc:firebirdsql:oo: (OpenOffice/LibreOffice driver) dropped
The OOREMOTE protocol (JDBC URL prefix jdbc:firebird[sql]:oo:
) has been removed in Jaybird 6.
The recommended replacement is to use LibreOffice and the builtin “Firebird External” connection option in LibreOffice Base, instead of the “JDBC” option with Jaybird on the classpath of LibreOffice.
8.6. Removed connection property timestampUsesLocalTimezone
The connection property timestampUsesLocalTimezone
has been removed.
The exact semantics and usage of this property were unclear.
It was previously deprecated in Jaybird 5 for removal in Jaybird 6 or later.
Other code associated with this property was also removed.
8.7. Differences in client info property behavior
The rewritten client info properties implementation may result in the following incompatibilities:
-
setClientInfo(Properties)
will now clear all known properties ofUSER_SESSION
and — if not in auto-commit —USER_TRANSACTION
which are not included in theProperties
object; Jaybird 5 and earlier only set properties listed in theProperties
object. The recommended approach is to usegetClientInfo()
, modify the returnedProperties
object (update values, add new properties, and remove properties which should be cleared), and callsetClientInfo(Properties)
with that object. -
Initially, a connection only knows the properties
ApplicationName
,ClientUser
andClientHostname
. Other properties are registered for the current connection when getting or setting properties. -
getClientInfo(String)
with a name without context will now always return the value fromUSER_SESSION
; Jaybird 5 and earlier returned the value inUSER_TRANSACTION
and fell back toUSER_SESSION
if the property did not exist inUSER_TRANSACTION
. To get the value fromUSER_TRANSACTION
, use<name>@USER_TRANSACTION
. -
If the property
ApplicationName
inUSER_SESSION
has no value, it falls back toCLIENT_PROCESS
inSYSTEM
(which reports the value of theprocessName
connection property); Jaybird 5 and earlier reportednull
without falling back.
See also Rewritten client info properties support.
8.8. New Operation.Type value for async fetch
With the introduction of async fetch, the org.firebirdsql.gds.ng.monitor.Operation.Type
enum has two new values added:
STATEMENT_ASYNC_FETCH_START
|
Start of async fetch. Covers sending of the fetch request. This operation is cancellable. |
STATEMENT_ASYNC_FETCH_COMPLETE
|
Completion of async fetch. Covers processing the responses of the fetch request. This operation is not cancellable. Attempts to cancel this operation will throw an exception. |
If you’re currently using the OperationAware
interface to monitor and/or cancel fetches, make sure to also process STATEMENT_ASYNC_FETCH_START
and/or STATEMENT_ASYNC_FETCH_COMPLETE
as appropriate.
8.9. Changes in datetime conversions
The conversions of datetime values were overhauled to use the java.time
types wherever possible.
This results in some minor differences:
-
getString(…)
on aTIME
field will now render fractional seconds if available -
setString(…)
on aTIME
field now has seconds optional and accepts fractional seconds -
setTime(…)
on aTIME
field will not set sub-second values (previously this could vary with the millisecond value wrapped byjava.sql.Time
) -
getString(…)
on aTIMESTAMP
field will now render without.0
at the end if the value does not have fractional seconds (e.g.2023-07-22 12:43:45
instead of2023-07-22 12:43:45.0
) -
setString(…)
on aTIMESTAMP
field now has seconds optional -
setString(…)
on aTIMESTAMP
field now also accepts ISO 8601 datetime strings (that is, with aT
as a separator instead of a space, for example,2023-07-22 12:43:45
and2023-07-22T12:43:45
are now both accepted) -
setDate(…)
on aTIMESTAMP
field now sets time to 00:00:00 (previously this could vary with the millisecond value wrapped byjava.sql.Date
) -
setTime(…)
on aTIMESTAMP
field will now always set at 1970-01-01, and will not set sub-second values (previously this could vary with the millisecond value wrapped byjava.sql.Time
) -
setTimestamp(…)
on aCHAR
/VARCHAR
/BLOB SUB_TYPE TEXT
field will now set the value without.0
at the end if the value does not have fractional seconds (e.g.2023-07-22 12:43:45
instead of2023-07-22 12:43:45.0
) -
getTimestamp(…)
on aCHAR
/VARCHAR
/BLOB SUB_TYPE TEXT
field will now also parse ISO 8601 datetime strings (that is, with aT
as a separator instead of a space, for example,2023-07-22 12:43:45
and2023-07-22T12:43:45
are now both accepted), and seconds are now optional -
getTime(…)
on aCHAR
/VARCHAR
/BLOB SUB_TYPE TEXT
field will now parse values without seconds and values with fractional seconds. Though it can parse it, the resulting value will not include fractional seconds. -
setDate(…, Calendar)
on aCHAR
/VARCHAR
/BLOB SUB_TYPE TEXT
field will now use theCalendar
to rebase the date, this can result in an off-by-one difference in the date compared to previous versions (depending on the time zone set on theCalendar
) -
getDate(…, Calendar)
on aCHAR
/VARCHAR
/BLOB SUB_TYPE TEXT
field will now use theCalendar
to rebase the date, this can result in an off-by-one difference in the date compared to previous versions (depending on the time zone set on theCalendar
) -
The
TypeConversionException
thrown bygetDate(…)
,getTime(…)
andgetTimestamp(…)
on unsupported types may now reportjava.time.LocalDate
,java.time.LocalTime
orjava.time.LocalDateTime
as the type in its error message instead ofjava.sql.Date
,java.sql.Time
, orjava.sql.Timestamp
8.10. Execution of COMMIT
and ROLLBACK
rejected by default
Attempts to prepare or execute COMMIT
or ROLLBACK
(without RETAIN
or a savepoint) will now fail by default.
In previous versions, executing these statements would work, but leave the connection in an unusable state.
The exact error will — generally — be one of the following:
337248313
|
“Execution of COMMIT statement is not allowed, use Connection.commit(), or set connection property allowTxStmts to true” |
337248314
|
“Execution of ROLLBACK statement is not allowed, use Connection.rollback(), or set connection property allowTxStmts to true” |
337248319
|
“Using addBatch with a transaction management statement is not supported” |
337248320
|
“Using prepareCall with a transaction management statement is not supported” |
In the case of the execute
, executeUpdate
or executeLargeUpdate
methods of Statement
, or the prepareStatement
methods of Connection
, this can be resolved by allowing the execution with connection property allowTxStmts
set to true
.
In the case of Statement.executeQuery(String)
and PreparedStatement.executeQuery()
, you will need to switch to using one of the other execute
, executeUpdate
or executeLargeUpdate
methods.
It is not possible to use the prepareCall
methods of Connection
with these statements.
In previous versions of Jaybird, subsequent execution wouldn’t work either — or attempt to execute stored procedures called COMMIT
or ROLLBACK
, but it is now rejected early in the prepareCall
methods of Connection
.
Switch to using prepareStatement
.
Additionally, using Statement.addBatch(String)
and PreparedStatement.addBatch()
will not work with these statements.
Switch to using one of the normal execute methods.
8.11. Forward-only holdable result sets no longer upgraded to scroll-insensitive
Jaybird no longer upgrades TYPE_FORWARD_ONLY
holdable result sets to TYPE_SCROLL_INSENSITIVE
.
As a result, for these result sets, only the next()
navigation method is allowed, and other navigation methods will throw an SQLException
, just like a forward-only non-holdable result set.
In previous versions this upgrade occurred when creating a TYPE_FORWARD_ONLY
result set, either explicitly when asking for holdability HOLD_CURSORS_OVER_COMMIT
, or implicitly when defaultResultsetHoldable=true
(or defaultHoldable=true
or result_set_holdable=true
) and no holdability was specified.
If you relied on this type upgrade to access navigation methods other than next()
, you will need to explicitly ask for a TYPE_SCROLL_INSENSITIVE
result set.
8.12. Read-only behaviour of connections
In previous versions of Jaybird the read-only state of a connection was not retained if the transaction parameter buffer was replaced, for example by calls to setTransactionIsolation(int)
.
Now this has been corrected, it is possible that your code unexpectedly throws an exception with message “attempted update during read-only transaction [SQLState:42000, ISC error code:335544361]” (error isc_read_only_trans
).
You need to make sure to call setReadOnly(false)
if the connection was previously marked read-only.
If you’re using a connection pool, you need to ensure it properly resets the read-only state of the connection when checking in or checking out the connection.
For example, both Apache DBCP and Apache Tomcat connection pools requires the defaultReadOnly
property to be set (i.e. to false
), otherwise it will not reset the read-only state.
If overridden transaction mappings are used, and the default isolation level has isc_tpb_read
, the connection will be marked as read-only.
As a result, switching isolation levels will now also result in read-only transactions, even if the mapping of the other isolation level is defined with isc_tpb_write
.
You will need to explicitly call setReadOnly(false)
, or — better yet — do not override transaction mappings with a isc_tpb_read
, but always use isc_tpb_write
, and control read-only state only through setReadOnly
.
8.13. ResultSet
in auto-commit no longer closed after last row
For more information, see ResultSet
in auto-commit no longer closed after last row.
8.14. Behavioural changes for updatable scrollable ResultSet
For more information, see Changes to behaviour of updatable scrollable result sets.
8.15. Removal of classes, packages and methods without deprecation
Below list of removals may look daunting, but if you use Jaybird only as a JDBC driver, through the JDBC API, you’re likely unaffected. Although we list them as removed without deprecation, some were marked as deprecated retroactively in Jaybird 5.0.3 or later.
This section does not include all changes to packages or classes considered internal API.
8.15.1. Removal of packages without deprecation
The following packages have been removed in Jaybird 6 without deprecation:
-
org.firebirdsql.logging
; there is no replacement
Due to modularization, the following packages are no longer accessible when Jaybird is used from the modulepath:
jaybird
dependency
-
org.firebirdsql.gds.ng.dbcrypt.simple
-
org.firebirdsql.gds.ng.tz
-
org.firebirdsql.gds.ng.wire.auth.legacy
-
org.firebirdsql.gds.ng.wire.auth.srp
-
org.firebirdsql.gds.ng.wire.crypt.arc4
-
org.firebirdsql.gds.ng.wire.crypt.chacha
-
org.firebirdsql.gds.ng.wire.versionNN
(with NN, is10
,11
,12
,13
,15
,16
and18
) -
org.firebirdsql.jaybird
-
org.firebirdsql.jaybird.parser
-
org.firebirdsql.jaybird.props.internal
-
org.firebirdsql.jaybird.util
-
org.firebirdsql.jdbc.escape
-
org.firebirdsql.jdbc.meta
8.15.2. Removal of methods without deprecation
The following methods have been removed in Jaybird 6 without deprecation:
-
FBConnection
-
prepareMetaDataStatement(String, int, int)
; useprepareStatement(String, int, int, int, boolean, boolean)
-
getStatementListener()
; there is no replacement -
inTransaction()
; there is no replacement
-
-
JaybirdSystemProperties
-
isForceConsoleLogger()
; there is no replacement -
isDisableLogging()
; there is no replacement -
getLoggerImplementation()
; there is no replacement
-
-
FBCallableStatement
-
findOutParameter(String)
(protected); usegetAndAssertSingletonResultSet().findColumn(paramName)
; carefully check if that is the correct usage (the method was removed because the old usage within Jaybird resulted in mapping the wrong column)
-
-
FBProcedureCall
-
mapOutParamIndexToPosition(int, boolean)
; usemapOutParamIndexToPosition(int)
(equivalent to passingtrue
), there is no replacement for thefalse
behaviour
-
8.15.3. Removal of classes without deprecation
The following classes have been removed in Jaybird 6 without deprecation:
-
FbLocalDatabaseFactory
— unused since removal of LOCAL protocol implementation in Jaybird 5. -
DatatypeCoder.RawDateTimeStruct
(semi-internal API) — use one of thejava.time
types (LocalDateTime
,LocalDate
orLocalTime
). Though this class was publicly accessible throughResultSet.getObject/updateObject
andPreparedStatement.setObject
, it is internal API, and we expect it is unlikely to be actually used in user code. -
FBDriverConsistencyCheckException
— unused since the changes to client info properties.
The following classes are no longer accessible in Jaybird 6:
-
RowValueBuilder
is now package private
The following classes are no longer extensible in Jaybird 6 as they are now sealed
or final
:
-
FBPooledConnection
-
Visibility was also reduced to package-private
-
-
FBXAConnection
-
Visibility was also reduced to package-private
-
-
PooledConnectionHandler
-
Class was already package-private
-
-
XAConnectionHandler
-
Visibility was also reduced to package-private
-
-
StoredProcedureMetaDataFactory
-
Visibility was also reduced to package-private
-
8.15.4. Removal of constants without deprecation
The following constants have been removed in Jaybird 6 without deprecation:
-
JaybirdSystemProperties
-
FORCE_CONSOLE_LOGGER_PROP
; there is no replacement -
DISABLE_LOGGING_PROP
; there is no replacement -
LOGGER_IMPLEMENTATION_PROP
; there is no replacement
-
-
SQLStateConstants
-
SQL_STATE_INVALID_CONN_ATTR
(01S00
) — it was unused; there is no replacement -
SQL_STATE_INVALID_COLUMN
(HY002
); replaced bySQL_STATE_INVALID_DESC_FIELD_ID
(HY091
) -
SQL_STATE_INVALID_ARG_VALUE
(HY009
); used with wrong meaning, replaced by multiple other constants (SQL_STATE_INVALID_USE_NULL
(HY009
, same value),SQL_STATE_ATT_CANNOT_SET_NOW
(HY011
) ,SQL_STATE_INVALID_ATTR_VALUE
(HY024
),SQL_STATE_INVALID_STRING_LENGTH
(HY090
)) -
SQL_STATE_INVALID_TRANSACTION_STATE
(25S01
) — it was unused; there is no replacement -
SQL_STATE_TRANSACTION_ACTIVE
(25S02
) — it was unused; there is no replacement -
SQL_STATE_TRANSACTION_ROLLED_BACK
(25S03
) — it was unused; there is no replacement -
SQL_STATE_CONNECTION_FAILURE_IN_TX
(08007
) — it was unused; there is no replacement -
SQL_STATE_COMM_LINK_FAILURE
(08S01
) — it was unused; there is no replacement
-
-
FBProcedureCall
-
OLD_CALLABLE_STATEMENT_COMPATIBILITY
; there is no replacement
-
8.16. Removal of deprecated classes, packages and methods
Below list of removals may look daunting, but if you use Jaybird only as a JDBC driver, through the JDBC API, you’re likely unaffected.
8.16.1. Removal of deprecated packages
The following packages have been removed in Jaybird 6:
-
org.firebirdsql.gds.impl.oo
-
org.firebirdsql.jdbc.oo
8.16.2. Removal of deprecated methods
The following methods have been removed in Jaybird 6:
-
FirebirdConnectionProperties
Changes to theFirebirdConnectionProperties
interface affect the data source implementations inorg.firebirdsql.ds
, andFBManagedConnectionFactory
.-
getDatabase()
and all its implementations; useDatabaseConnectionProperties.getDatabaseName()
-
setDatabase(String)
and all its implementations; useDatabaseConnectionProperties.setDatabaseName(String)
-
getNonStandardProperty(String)
and all its implementations; useBaseProperties.getProperty(String)
-
setNonStandardProperty(String,String)
and all its implementations; useBaseProperties.setProperty(String,String)
-
getBuffersNumber
and all its implementations; useDatabaseConnectionProperties.getPageCacheSize
-
setBuffersNumber
and all its implementations; useDatabaseConnectionProperties.setPageCacheSize
-
-
IConnectionProperties
-
short getConnectionDialect()
and all its implementations; useint DatabaseConnectionProperties.getSqlDialect()
-
setConnectionDialect(short)
, and all its implementations; useDatabaseConnectionProperties.setSqlDialect(int)
-
-
FBSimpleDataSource.get/setBlobBufferLength
; useget/setBlobBufferSize
-
EventManager
-
get/setHost
; useget/setServerName
-
get/setPort
; useget/setPortNumber
-
get/setDatabase
; useget/setDatabaseName
-
-
GDSFactory.getJdbcUrl(GDSType, String)
; useGDSFactory.getJdbcUrl(GDSType, DatabaseConnectionProperties)
-
FBManagedConnection.getDatabase()
; there is no direct replacement, but the information can be obtained from the connection properties -
GDSHelper.getIscEncoding()
; there is no replacement -
FirebirdConnection.getIscEncoding
; there is no replacement -
FBBlob
-
constructors
FBBlob(GDSHelper)
andFBBlob(GDSHelper, FBObjectListener.BlobListener)
; useFBBlob(GDSHelper, FBObjectListener.BlobListener, Config)
-
constructors
FBBlob(GDSHelper c, long blobId)
andFBBlob(GDSHelper c, long blobId, FBObjectListener.BlobListener blobListener)
; useFBBlob(GDSHelper, long, FBObjectListener.BlobListener, Config)
-
-
DatabaseConnectionProperties
-
isTimestampUsesLocalTimezone
/setTimestampUsesLocalTimezone(boolean)
; there is no replacement
-
-
FBSQLException
-
constructor
FBSQLException(String, SQLException)
; useFBSQLException(String)
orFBSQLException(String, String)
followed bysetNextException(SQLException)
-
getInternalException()
; usegetCause()
-
-
FBServiceManager
-
executeServicesOperation(ServiceRequestBuffer)
; useexecuteServicesOperation(FbService, ServiceRequestBuffer)
-
-
FirebirdDriver
(andFBDriver
)-
newConnectionProperties()
— was not previously deprecated, see next method -
connect(FirebirdConnectionProperties)
; useFBSimpleDataSource
for programmatic access to connection properties and connection creation
-
8.16.3. Removal of deprecated classes
The following classes have been removed in Jaybird 6:
-
org.firebirdsql.gds.ng.listeners.DefaultDatabaseListener
; implementingDatabaseListener
is now sufficient as all methods in the interface now have a default implementation that does nothing -
org.firebirdsql.gds.ng.listeners.DefaultStatementListener
; implementingStatementListener
is now sufficient as all methods in the interface now have a default implementation that does nothing -
org.firebirdsql.jdbc.FBConnectionDefaults
; its replacement,org.firebirdsql.jaybird.props.PropertyConstants
, is considered internal API
8.16.4. Removal of deprecated constants
The following constants have been removed in Jaybird 6:
-
All public String constants in
FBDriver
; the replacement for most constants can be found inorg.firebirdsql.jaybird.props.PropertyNames
, though some will be removed without replacement -
ISCConstants.isc_dpb_*
that are DPB items; the replacement is the constant with the same name inorg.firebirdsql.jaybird.fb.constants.DpbItems
-
ISCConstants.isc_tpb_*
that are TPB items; the replacement is the constant with the same name inorg.firebirdsql.jaybird.fb.constants.TpbItems
-
ISCConstants.isc_spb_*
that are SPB items; the replacement is the constant with the same name inorg.firebirdsql.jaybird.fb.constants.SpbItems
-
ISCConstants.isc_bpb_*
that are BPB items; the replacement is the constant with the same name inorg.firebirdsql.jaybird.fb.constants.BpbItems
-
ISCConstants.isc_bpb_type_segmented
andISCConstants.isc_bpb_type_stream
; the replacement is the constant with the same name inorg.firebirdsql.jaybird.fb.constants.BpbItems.TypeValues
-
All constants in
DatabaseParameterBuffer
; use the equivalent constant fromorg.firebirdsql.jaybird.fb.constants.DpbItems
-
All constants in
TransactionParameterBuffer
; use the equivalent constant fromorg.firebirdsql.jaybird.fb.constants.TpbItems
-
All constants in
ServiceParameterBuffer
; use the equivalent constant fromorg.firebirdsql.jaybird.fb.constants.SpbItems
-
All constants in
BlobParameterBuffer
; use the equivalent constant fromorg.firebirdsql.jaybird.fb.constants.BpbItems
andorg.firebirdsql.jaybird.fb.constants.BpbItems.TypeValues
-
All
TPB_*
constants inFirebirdConnection
; use the equivalent constant fromorg.firebirdsql.jaybird.fb.constants.TpbItems
-
All public String constants in
org.firebirdsql.jdbc.FBConnectionProperties
; the replacement for most constants can be found inorg.firebirdsql.jaybird.props.PropertyNames
, though some will be removed without replacement -
GDSHelper.DEFAULT_BLOB_BUFFER_SIZE
; its replacement,org.firebirdsql.jaybird.props.PropertyConstants.DEFAULT_BLOB_BUFFER_SIZE
, is considered internal API -
All constants in
IConnectionProperties
; use the equivalent constant fromorg.firebirdsql.jaybird.props.PropertyConstants
, though this class is considered internal API -
All constants in
IServiceProperties
; use the equivalent constant fromorg.firebirdsql.jaybird.props.PropertyConstants
, though this class is considered internal API -
PropertyNames.timestampUsesLocalTimezone
; there is no replacement
8.17. Breaking changes internal API
The following breaking changes were made to the internal API, like the GDS-ng API in org.firebirdsql.gds.ng
and sub-packages.
These changes are primarily interesting for implementers of custom GDS-ng implementations or forks of Jaybird, or people using these low-level APIs directly.
Only changes we think are relevant to driver implementers or (internal) API users are documented. This means there may be undocumented changes to internal API. If you are confronted with such a change, let us know on firebird-java, so we can take this into account when documenting future changes. |
-
FbWireDatabase
-
enqueueDeferredAction(DeferredAction)
now throwsSQLException
to be able to handle exceptions for sync actions if there are a lot of deferred packets
-
-
FbWireOperations
-
enqueueDeferredAction(DeferredAction)
now throwsSQLException
(see alsoFbWireDatabase
above)
-
-
AbstractFbStatement
-
setCursorName(String)
is now final; subclasses need to implementsetCursorNameImpl(String)
to provide the actual implementation. These implementations do not need to take out the lock, nor notify the exception listener dispatcher, as that is already handled in the finalsetCursorName(String)
method. -
The most recent cursor name is now accessible with
protected String getCursorName()
. Its value is reset tonull
on each prepare.
-
-
AbstractFbWireStatement
-
close()
is now final -
wrapDeferredResponse
received an extra parameter,boolean requiresSync
. This parameter signals if the deferred response requires some form of synchronization action to instruct the server to send the response. When in doubt, usefalse
to communicate that no such synchronization is required.
-
-
JnaDatabase
-
getEncodingDefinition
was removed; there is no replacement
-
-
DeferredAction
-
wrapDeferredResponse
received an extra parameter,boolean requiresSync
. This parameter signals if the deferred response requires some form of synchronization action to instruct the server to send the response. When in doubt, usefalse
to communicate that no such synchronization is required.
-
-
AsynchronousChannelListener.Event
was converted to a record, so it is now final, and its getters (getEventId()
andgetEventCount()
) have been replaced by accessor methods (eventId()
andeventCount()
) -
DbAttachInfo
was converted to a record, so its getters (getServerName()
,getPortNumber()
andgetAttachObjectName()
) have been replaced by accessor methods (serverName()
,portNumber()
,attachObjectName()
) -
XdrInputStream
-
skipPadding
return type was changed tovoid
as the return value is never used in Jaybird code -
skipFully
was removed; use standard JavaInputStream.skipNBytes
instead -
readShort
was removed as it was unused
-
-
The no-arg constructor of
FBXAException
was removed -
FBResultSet
-
close(boolean)
was removed; useclose(boolean, CompletionReason)
-
-
FBProcedureCall
is no longer cloneable; useFBProcedureCall.copyOf(FBProcedureCall)
-
UnixCrypt
was replaced byLegacyHash
, which only performs the password hash specific to Firebird legacy authentication -
GDSFactoryPlugin.getDatabasePath(String, Integer, String)
andgetDatabasePath(String)
no longer throwGDSException
, but instead throwSQLException
-
GDSFactory.getDatabasePath(…)
no longer throwGDSException
, but instead throwSQLException
-
GDSServerVersionException
no longer extendsGDSException
, but instead extendsSQLNonTransientException
-
GDSException
was significantly modified and deprecated for future removal. Most of its implementation was removed, and it now extendsSQLException
. Only the constructorsGDSException(int)
,GDSException(int, Throwable)
andGDSException(String)
were retained. All other constructors and methods have been removed. -
WireGDSFactoryPlugin
,NativeGDSFactoryPlugin
andEmbeddedGDSFactoryPlugin
are now final -
FbEmbeddedDatabaseFactory
is now final -
FbClientDatabaseFactory
andFbEmbeddedDatabaseFactory
now have a private constructor; use their staticgetInstance()
method to obtain an instance -
DefaultDatatypeCoder.intToBytes(int)
was removed; useencodeInt(int)
-
ChaChaEncryptionPlugin
andChaChaEncryptionPluginSpi
are now final -
CryptSessionConfig
, the JavaBeans-style accessors have been replaced with record-style accessors:-
getEncryptionIdentifier()
→encryptionIdentifier()
-
getEncryptKey()
→encryptKey()
-
getDecryptKey()
→decryptKey()
-
getSpecificData()
→specificData()
-
-
EncryptionIdentifier
, some JavaBeans-style accessors have been replaced with record-style accessors:-
getType()
→type()
-
getPluginName()
→pluginName()
-
-
KnownServerKey.PluginSpecificData
, the JavaBeans-style accessors have been replaced with record-style accessors:-
getEncryptionIdentifier()
→encryptionIdentifier()
-
getSpecificData()
→specificData()
-
-
EncryptionPlugin
andEncryptionPluginSpi
, the JavaBeans-style accessor has been replaced with a record-style accessor:-
getEncryptionIdentifier()
→encryptionIdentifier()
-
-
StringArgument
-
constructor
StringArgument(int, ArgumentType, String)
; useStringArgument(int, ArgumentType, String, Encoding)
-
-
FBConnection
-
checkClientInfoSupport()
was removed; there is no replacement
-
-
IEncodingFactory
-
<T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T>)
was removed; its replacements is<T extends DatatypeCoder> T getOrCreateDatatypeCoder(Class<T>, Function<IEncodingFactory, T>)
where the function is a factory for the desiredDatatypeCoder
instance if it doesn’t already exist.
-
-
The following classes in
org.firebirdsql.util
were moved toorg.firebirdsql.jaybird.util
. This package is internal API only, and not exported from the module.-
ByteArrayHelper
-
ExceptionHelper
-
IOUtils
-
Primitives
-
ReflectionHelper
-
SQLExceptionChainBuilder
-
StringUtils
-
-
DbMetadataMediator
was moved to packageorg.firebirdsql.jdbc
for module accessibility reasons. -
DatatypeCoder
-
encodeTimestamp(Timestamp, Calendar, boolean)
was removed; there is no replacement -
decodeTimestamp(Timestamp, Calendar, boolean)
was removed; there is no replacement -
encodeTimestampCalendar(Timestamp, Calendar)
was removed; useencodeLocalDateTime(LocalDateTime)
-
decodeTimestampCalendar(byte[], Calendar)
was removed; usedecodeLocalDateTime(byte[])
-
encodeTimestampRaw(DatatypeCoder.RawDateTimeStruct)
was removed; useencodeLocalDateTime(LocalDateTime)
-
decodeTimestampRaw(byte[])
was removed; usedecodeLocalDateTime(byte[])
-
encodeTime(Time, Calendar, boolean)
was removed; there is no replacement -
decodeTime(Time, Calendar, boolean)
was removed; there is no replacement -
encodeTimeCalendar(Time, Calendar)
was removed; useencodeLocalTime(LocalTime)
-
decodeTimeCalendar(byte[], Calendar)
was removed; usedecodeLocalTime(byte[])
-
encodeTimeRaw(DatatypeCoder.RawDateTimeStruct)
was removed; useencodeLocalTime(LocalTime)
-
decodeTimeRaw(byte[])
was removed; usedecodeLocalTime(byte[])
-
encodeDate(Date, Calendar)
was removed; there is no replacement -
decodeDate(Date, Calendar)
was removed; there is no replacement -
encodeDateCalendar(Date, Calendar)
was removed; useencodeLocalDate(LocalDate)
-
decodeDateCalendar(byte[], Calendar)
was removed; usedecodeLocalDate(byte[])
-
encodeDateRaw(DatatypeCoder.RawDateTimeStruct)
was removed; useencodeLocalDate(LocalDate)
-
decodeDateRaw(byte[])
was removed; usedecodeLocalDate(byte[])
-
-
FetchResponse
was converted to a record, and its getters (getStatus()
andgetCount()
) have been replaced by accessor methods (status()
andcount()
) -
GenericResponse
was converted to a record, and its getters (getObjectHandle()
,getBlobId()
,getData()
andexception()
) have been replaced by accessor methods (objectHandle()
,blobId()
,data()
andexception()
) -
SQLResponse
was converted to a record, and its getter (getCount()
) has been replaced by an accessor method (count()
) -
SQLExceptionChainBuilder
-
Moved to package
org.firebirdsql.jaybird.util
; this package is internal API only, and not exported from the module (see also earlier) -
The generics
<E extends SQLException>
were removed from this class-
append
andaddFirst
now always expectSQLException
-
getException()
now always returnsSQLException
-
-
Constructor
SQLExceptionChainBuilder(SQLException)
was removed, as in practice this was never used; replacement isnew SQLExceptionChainBuilder().append(exception)
-
-
FBTpb
was removed, and its usages were replaced withTransactionParameterBuffer
-
FBTpbMapper
no longer implementsCloneable
, useFBTpbMapper.copyOf(FBTpbMapper)
instead -
ParameterBuffer
now extendsSerializable
, as all implementations are serializable, and some usages expect serializable behaviour even when the interfaces were used (though in practice, these objects are hardly ever serialized) -
FBManagedConnection
-
setReadOnly(boolean)
was renamed tosetTpbReadOnly(boolean)
to reflect what it actually does -
isReadOnly()
was renamed toisTpbReadOnly()
to reflect what it actually does
-
-
FBObjectListener.FetcherListener
-
fetcherClosed(FBFetcher)
was removed -
allRowsFetched(FBFetcher)
was removed
-
-
FBObjectListener.ResultSetListener
-
allRowsFetched(ResultSet)
was removed
-
8.18. Unlikely breaking changes
The following changes might cause issues, though we think this is unlikely:
8.18.1. Removal of finalization
With the removal of finalization, the replacement cleanup has been simplified, and in some cases left out entirely.
Possible effects include:
-
If a close/cleanup is performed by the
Cleaner
, listeners will not get notified. Given it is unlikely there will not be strong reference to an object if something is still interested in its listener events, we think this is acceptable. -
The closing of a pure Java connection which was not explicitly closed is now simply a socket close handled by the cleanup action of the socket itself. Server-side this may result in delayed cleanup of a connection and its resources, and occurrences of “connection reset by peer” (e.g. error 10054 on Windows, error 104 on Linux). If you see an increase of these errors, we recommend you hunt for connection leaks in your application.
8.18.2. Conversion from double to BigDecimal
Conversions from double
to java.math.BigDecimal
now always use BigDecimal.valueOf(double)
.
Previously, a combination of new BigDecimal(double)
and BigDecimal.valueOf(double)
was used.
This change may result in minor differences in precision or rounding of values.
8.19. Breaking changes for Jaybird 7
With Jaybird 7 the following breaking changes will be introduced.
8.19.1. Removal of deprecated classes, packages and methods
Removal of deprecated methods
The following methods will be removed in Jaybird 7:
-
GDSFactoryPlugin
(semi-internal API)-
getTypeAliases()
— usegetTypeAliasList()
-
getSupportedProtocols
— usegetSupportedProtocolList()
-
-
GDSHelper
(internal API)-
startTransaction(TransactionParameterBuffer)
— useFbDatabase.startTransaction(TransactionParameterBuffer)
followed byGDSHelper.setCurrentTransaction(FbTransaction)
-
-
FirebirdStatement
-
getCurrentResultSet()
— usegetResultSet()
-
-
SqlCountHolder
(internal API)-
getLongUpdateCount()
— useupdateCount()
-
getLongDeleteCount()
— usedeleteCount()
-
getLongInsertCount()
— useinsertCount()
-
getLongSelectCount()
— useselectCount()
-
Removal of deprecated classes
The following classes have been deprecated and will be removed in Jaybird 7:
-
GDSException
; useSQLException
or one of its (normal) subclasses. Previous versions ofGDSFactoryPlugin
declaredthrows GDSException
for some methods, but nowthrows SQLException
. To retain some semblance of backwards-compatibility, this class was retrofitted to extendSQLException
. -
FBSQLException
; useSQLException
8.19.2. Removal of deprecated constants
The following constants have been deprecated and will be removed in Jaybird 7:
-
ISCConstants
-
isc_isc_sql_dialect_conflict_num
(was already deprecated, now for removal); useisc_sql_dialect_conflict_num
-
isc_err_max
; there is no replacement
-
-
QuoteStrategy
— due to addition of methodsappendLiteral
andquoteLiteral
the original enum names no longer made sense-
NO_QUOTES
— useDIALECT_1
-
QUOTES
— useDIALECT_3
-
9. Compatibility notes
9.1. Type 2 (native) and embedded driver
Since Jaybird 6, the native and embedded part of the driver has been moved to a separate artifact, jaybird-native
.
The Jaybird Native GDS Factory plugin uses JNA to access the client library.
If you want to use the Type 2 driver, or Firebird embedded, then you need to include jaybird-native-6.0.0-beta-1
and jna-jpms-5.15.0.jar
on the classpath.
When using Maven, you need to specify the dependency on jaybird-native
:
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird-native</artifactId>
<version>6.0.0-beta-1</version>
</dependency>
The fbclient.dll
, fbembed.dll
, libfbclient.so
, or libfbembed.so
need to be on the path, or the location needs to be specified in the system property jna.library.path
(as an absolute or relative path to the directory/directories containing the library file(s)).
For Windows and Linux, you can add the org.firebirdsql.jdbc:fbclient
dependency on your classpath to provide the native libraries for the native
and local
protocol.
Be aware that this dependency does not support embedded
.
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>fbclient</artifactId>
<version>5.0.1.1</artifactId>
</dependency>
For more information about this library, see https://github.com/mrotteveel/jaybird-fbclient.
In the future we may provide JARs with the embedded libraries of a specific Firebird version.