An existing question expresses something similar, but I want to call out a slightly different nuance here.
The basic question: All application servers give the ability to specify both the (standard) interface and the (vendor-supplied) implementation classes for a (little-d, little-s) data source when you define a connection pool. If a vendor supplies an implementation for both a ConnectionPoolDataSource
and a regular ol' DataSource
, which one is to be preferred?
What about for vendor implementations that implement DataSource
, ConnectionPoolDataSource
and XADataSource
in the same implementation class?
The documentation for javax.sql.ConnectionPoolDataSource
says, almost in total:
A factory for PooledConnection objects. An object that implements this interface will typically be registered with a naming service that is based on the JavaTM Naming and Directory Interface (JNDI).
That's basically useless, but it is worth noting that javax.sql.ConnectionPoolDataSource
does not itself extend javax.sql.DataSource
, which means that implementations of it need not provide a getConnection()
method, which is the one most callers are accustomed to using. This tells me that all application servers MUST either:
wrap a
javax.sql.ConnectionPoolDataSource
implementation with ajavax.sql.DataSource
implementation so that callers can usejavax.sql.DataSource#getConnection()
, ordetect that a
javax.sql.ConnectionPoolDataSource
implementation is also ajavax.sql.DataSource
implementation, and (somehow) trust that itsgetConnection()
method will delegate togetPooledConnection()
(how on earth would they do this?)
The documentation for javax.sql.DataSource
says, in part:
The DataSource interface is implemented by a driver vendor. There are three types of implementations:
- Basic implementation -- produces a standard Connection object
- Connection pooling implementation -- produces a Connection object that will automatically participate in connection pooling. This implementation works with a middle-tier connection pooling manager.
- Distributed transaction implementation -- produces a Connection object that may be used for distributed transactions and almost always participates in connection pooling. This implementation works with a middle-tier transaction manager and almost always with a connection pooling manager.
This is also useless, and incorrect to boot (or at least underspecified: javax.sql.DataSource
is also implemented by application server vendors, who must provide an implementation so that client code may (for example) inject a javax.sql.DataSource
into their server-side code). It also seems to imply that connection pooling might or might not be offered by any given DataSource
implementation, which would make me wonder how an application server is supposed to tell when a connection pool is set up that has specified the javax.sql.DataSource
interface (instead of the javax.sql.ConnectionPoolDataSource
interface).
Note: I am not looking for an answer here about How I Did This On Tomcat, or The Steps I Took On GlassFish That Worked For Me or anything of that nature. I'm looking for an answer that refers back to the JDBC specification, or the Java EE specification, or a bug report, or something that indicates why these separate (unrelated!) interfaces exist, and how they are supposed to be unified or distinguished between on a generic Java EE application server that is therefore obligated to offer connection pooling.