The Java Database Connectivity (JDBC) standard provides an API for applications to interact with relational database systems from different vendors. To abstract over concrete database systems and vendor specific characteristics, the JDBC specification provides various classes and Service Provider Interfaces (SPI) that can be used for database interaction. Implementations are database specific and provided by the corresponding driver. This specification defines how OSGi-aware JDBC drivers can provide access to their implementations. Applications can rely on this mechanism to transparently access drivers and to stay independent from driver specific classes. Additionally, this mechanism helps to use common OSGi practices and to avoid class loading problems.
This specification uses a number of packages that are defined in Java SE 1.4 or later.
-
Registration - Provide a mechanism for JDBC driver announcements.
-
Lookup - Inspect available database drivers and provide means for driver access.
-
Services - Uses a service model for getting the driver objects.
-
Compatible - Minimize the amount of work needed to support this specification for existing drivers.
-
Relational Database Management Systems - (RDBMS) An external database system.
-
Database Driver - JDBC-compliant database driver that is delivered in a bundle.
-
Data Source Factory - Provides one of the different Data Sources that gives access to a database driver.
-
Application - The application that wants to access a relational database system.
The classes and interfaces used in this specification come from the following packages:
javax.sql
java.sql
These packages have no associated version. It is assumed they come from the runtime environment. This specification is based on Java SE 1.4 or later.
A JDBC Database Driver is the software that
maps the JDBC specification to a specific implementation of a relational
database. For OSGi, JDBC drivers are delivered as driver bundles. A
driver bundle registers a Data Source Factory service when it is
ACTIVE
. Service properties are used to specify the database
driver name, version, etc. The Data Source Factory service provides
methods to create DataSource
,
ConnectionPoolDataSource
, XADataSource
, or
Driver
objects. These objects are then used by an
application to interact with the relational database system in the
standard way.
The application can query the service registry for available Data Source Factory services. It can select particular drivers by filtering on the service properties. This service based model is easy to use with dependency injection frameworks like Blueprint or Declarative Services.
A Database Driver provides the connection between an Application and a particular database. A single OSGi Framework can contain several Database Drivers simultaneously. To make itself available to Applications, a Database Driver must register a Data Source Factory service. Applications must be able to find the appropriate Database Driver. The Database Driver must therefore register the Data Source Factory service with the following service properties:
-
OSGI_JDBC_DRIVER_CLASS - (
String
) The required name of the driver implementation class. This property is the primary key to find a driver's Data Source Factory. It is not required that there is an actual class with this name. -
OSGI_JDBC_DRIVER_NAME - (
String
) The optional driver name. This property is informational. -
OSGI_JDBC_DRIVER_VERSION - (
String
) The driver version. The version is not required to be an OSGi version, it should be treated as an opaque string. This version is likely not related to the package of the implementation class or its bundle.
The previous properties are vendor-specific and are meant to further describe the Database Driver to the Application.
Each Data Source Factory service must relate to a single Database Driver. The Database Driver implementation bundle does not necessarily need to be the registrar of the Data Source Factory service. Any bundle can provide the Data Source Factory service and delegate to the appropriate driver specific implementation classes. However, as JDBC driver implementations evolve to include built-in support for OSGi they can provide the Data Source Factory service themselves. This implies that the same driver can be registered multiple times.
A Data Source Factory service should be registered while its
Driver Bundle is in the ACTIVE
state or when it has a
lazy
activation policy and is in the STARTING
state.
What happens to the objects created by the Data Source Factory service, and the objects they created, is undefined in this specification. Database Drivers are not mandated to track the proper life cycle of these objects.
A Database Driver must import the javax.sql
package.
The java.sql
package that contains the Driver
and SQLException
interface is automatically visible
because it starts with java.
. Both packages are contained
in the JRE since Java SE 1.4. These packages are not normally versioned
with OSGi version numbers. Bundles using the Data Source Factory must
therefore ensure they get the proper imports, which is usually from the
JRE. Due to the lack of specified metadata, the deployer is responsible
for ensuring this.
Applications can query the OSGi service registry for available Database Drivers by getting a list of Data Source Factory services. Normally, the application needs access to specific drivers that match their needed relational database type. The service properties can be used to find the desired Database Driver. This model is well supported by dependency injection frameworks like Blueprint or Declarative Services. However, it can of course also be used with the basic service methods. The following code shows how a Service Tracker can be used to get a Database Driver called ACME DB.
Filter filter = context.createFilter(
"(&(objectClass=" +
DataSourceFactory.class.getName() +
")(" +
DataSourceFactory.OSGI_JDBC_DRIVER_CLASS + "=com.acme.db.Driver))");
ServiceTracker tracker = new ServiceTracker(context, filter, null);
tracker.open();
DataSourceFactory dsf = (DataSourceFactory) tracker.getService();
The Data Source Factory service can be used to obtain instances for the following JDBC related types:
-
javax.sql.DataSource
-
javax.sql.ConnectionPoolDataSource
-
javax.sql.XADataSource
-
java.sql.Driver
Which type of Connection provider that is actually required
depends on the Application and the use case. For each type, the Data
Source Factory service provides a method that returns the corresponding
instance. Each method takes a Properties
object as a
parameter to pass a configuration to the Database Driver implementation.
The configuration is driver-specific and can be used to specify the URL
for the database and user credentials. Common property names for these
configuration properties are also defined in the
DataSourceFactory
interface.
A Data Source Factory is not required to implement all of the factory methods. If an implementation does not support a particular type then it must throw a SQL Exception. This specification does not provide a mechanism to depend on a Data Source Factory service that implements a particular factory method.
The following code shows how a DataSource
object
could be created.
Properties props = new Properties();
props.put(DataSourceFactory.JDBC_URL, "jdbc:acme:ACMEDB");
props.put(DataSourceFactory.JDBC_USER, "foo");
props.put(DataSourceFactory.JDBC_PASSWORD, "secret");
DataSource dataSource = dsf.createDataSource(props);
The DataSourceFactory
interface has several static
fields that represent common property keys for the
Properties
instance. General properties are:
The following additional property keys are provided for
applications that want to create a ConnectionPoolDataSource
object or a XAPoolDataSource
object:
Which property keys and values are supported depends on the driver implementation. Drivers can support additional custom configuration properties.
The JDBC service provides JDBC driver services, not
container services. A typical client would only use
the DataSourceFactory.createDataSource()
method to procure
a regular Data Source from which they can obtain (usually non-pooled)
connections.
Containers generally offer connection pools and support XA transactions. The container manages the pools and does this by using Pooled Connection or XA Connection objects from a driver-implemented respective Connection Pool Data Source or XA Data Source. To support containers, frameworks, or any client that wants to manage a pool, these Data Source types are included in the Data Source Factory service. Drivers are permitted to implement their own Data Source using an underlying connection pooling scheme. This is driver-dependent and not related to the OSGi specifications.
The usual set of JDBC properties are defined in the services for use with the Data Source types. They are the same as what is defined for JDBC and the caller should know which properties make sense when passed to a given Data Source type. The same result should occur in OSGi as occurs outside of OSGi. If the driver does not support a given property with a given Data Source type then it can ignore it or it can throw an Exception.
JDBC Service Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.jdbc; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.jdbc; version="[1.0,1.1)"
-
DataSourceFactory
- A factory for JDBC connection factories.
A factory for JDBC connection factories. There are 3 preferred connection
factories for getting JDBC connections: javax.sql.DataSource
,
javax.sql.ConnectionPoolDataSource
, and
javax.sql.XADataSource
.
DataSource providers should implement this interface and register it as an
OSGi service with the JDBC driver class name in the
OSGI_JDBC_DRIVER_CLASS property.
Thread-safe
The "databaseName" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "dataSourceName" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "description" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "initialPoolSize" property that ConnectionPoolDataSource and XADataSource clients may supply a value for when calling createConnectionPoolDataSource(Properties) or createXADataSource(Properties) on drivers that support this property.
The "maxIdleTime" property that ConnectionPoolDataSource and XADataSource clients may supply a value for when calling createConnectionPoolDataSource(Properties) or createXADataSource(Properties) on drivers that support this property.
The "maxPoolSize" property that ConnectionPoolDataSource and XADataSource clients may supply a value for when calling createConnectionPoolDataSource(Properties) or createXADataSource(Properties) on drivers that support this property.
The "maxStatements" property that ConnectionPoolDataSource and XADataSource clients may supply a value for when calling createConnectionPoolDataSource(Properties) or createXADataSource(Properties) on drivers that support this property.
The "minPoolSize" property that ConnectionPoolDataSource and XADataSource clients may supply a value for when calling createConnectionPoolDataSource(Properties) or createXADataSource(Properties) on drivers that support this property.
The "networkProtocol" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "password" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "portNumber" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "propertyCycle" property that ConnectionPoolDataSource and XADataSource clients may supply a value for when calling createConnectionPoolDataSource(Properties) or createXADataSource(Properties) on drivers that support this property.
The "roleName" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "serverName" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "url" property that DataSource clients should supply a value for when calling createDataSource(Properties).
The "user" property that DataSource clients should supply a value for when calling createDataSource(Properties).
Service property used by a JDBC driver to declare the driver class when registering a JDBC DataSourceFactory service. Clients may filter or test this property to determine if the driver is suitable, or the desired one.
Service property used by a JDBC driver to declare the driver name when registering a JDBC DataSourceFactory service. Clients may filter or test this property to determine if the driver is suitable, or the desired one.
Service property used by a JDBC driver to declare the driver version when registering a JDBC DataSourceFactory service. Clients may filter or test this property to determine if the driver is suitable, or the desired one.
The properties used to configure the
ConnectionPoolDataSource
. null
indicates no
properties. If the property cannot be set on the
ConnectionPoolDataSource
being created then a
SQLException
must be thrown.
Create a new ConnectionPoolDataSource
using the given properties.
A configured ConnectionPoolDataSource
.
SQLException
– If the ConnectionPoolDataSource
cannot be
created.
The properties used to configure the DataSource
.
null
indicates no properties. If the property cannot be
set on the DataSource
being created then a
SQLException
must be thrown.
Create a new DataSource
using the given properties.
A configured DataSource
.
SQLException
– If the DataSource
cannot be created.
The properties used to configure the Driver
.
null
indicates no properties. If the property cannot be
set on the Driver
being created then a
SQLException
must be thrown.
Create a new Driver
using the given properties.
A configured Driver
.
SQLException
– If the Driver
cannot be created.
The properties used to configure the XADataSource
.
null
indicates no properties. If the property cannot be
set on the XADataSource
being created then a
SQLException
must be thrown.
Create a new XADataSource
using the given properties.
A configured XADataSource
.
SQLException
– If the XADataSource
cannot be created.