You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by Knut Anders Hatlen <Kn...@Sun.COM> on 2006/07/24 11:47:10 UTC
Are separate JDBC 4.0 versions of the DataSource classes really needed?
Hi,
I started looking at our implementation of JDBC 4.0 data sources when
I saw Rick updating the documentation with information about using
Embedded*DataSource40 when running jvm>=1.6. I think it is problematic
to have this split between pre-JDBC4 data sources and JDBC4 data
sources for a number of reasons:
- it is confusing for the users to have thirteen different data
source implementations (EmbeddedSimpleDataSource,
EmbeddedDataSource, EmbeddedConnectionPoolDataSource,
EmbeddedXADataSource, EmbeddedDataSource40,
EmbeddedConnectionPoolDataSource40, EmbeddedXADataSource40,
ClientDataSource, ClientConnectionPoolDataSource,
ClientXADataSource, ClientDataSource40,
ClientConnectionPoolDataSource40, ClientXADataSource40)
- it is difficult to maintain and document properly
- applications that use data sources don't automatically start using
JDBC 4.0 when upgrading to Derby 10.2
- how should we name the classes when we start implementing JDBC
5.0? DataSource40 will be misleading and DataSource50 will only
increase the confusion (it would give a total of nineteen classes)
For the internal implementation classes, this is not a big problem
since the users don't see their names, but the DataSource classes are
in our published API and therefore visible to our users.
The rationale behind adding new classes for the JDBC 4.0 data sources
was that they contained generic method signatures which wouldn't
compile under jdk<1.6. The problematic method signatures are
<T> T unwrap(Class<T>)
<T extends BaseQuery> createQueryObject(Class<T>)
<T extends BaseQuery> createQueryObject(Class<T>, DataSource)
However, the actual signatures of the compiled methods are
Object unwrap(Class)
BaseQuery createQueryObject(Class)
BaseQuery createQueryObject(Class, DataSource)
I tried to put these methods with modified signatures into
EmbeddedDataSource and removed them from Embedded*DataSource40. To
make it compile, I had to modify the build.xml script to add an empty
java.sql.BaseQuery class to the classpath when compiling
EmbeddedDataSource.
The conclusion from this experiment was: it compiles, it runs under
jvm1.6 (jdbc40 suite passed without errors), and it runs under jvm1.3,
jvm1.4 and jvm1.5.
Does anyone see any serious problems with this approach? Although it's
a dirty hack, I think it is much better than shipping a double set of
data sources.
--
Knut Anders
Re: Are separate JDBC 4.0 versions of the DataSource classes really
needed?
Posted by Knut Anders Hatlen <Kn...@Sun.COM>.
Rick Hillegas <Ri...@Sun.COM> writes:
> Hi Knut Anders,
>
> I don't understand part of your experiment. The implementation of
> createQueryObject() refers to another class, QueryObjectFactory, which
> was introduced by JDK 1.6. How did EmbeddedDataSource compile with
> this reference?
We need to use reflection either in createQueryObject() or at class
load time. For instance, we could have a static initializer in
EmbeddedDataSource which sets a static field to an instance of a
helper class. We could have two versions of the helper class, one for
pre-jdbc4 and one for jdbc4. The pre-jdbc4 version has a
createQueryObject() method that returns null, and the jdbc4 version
invokes QueryObjectFactory.createQueryObject().
There is however one problem with my approach. The jdbc40 tests run
just fine because they are written against the DataSource interface,
but applications that use EmbeddedDataSource directly might get
problems at compile time.
This works fine
DataSource ds = getDataSourceFromSomewhere();
MyQuery mq = ds.createQueryObject(MyQuery.class);
but this won't compile
EmbeddedDataSource eds = (EmbeddedDataSource) getDataSourceFromSomewhere();
MyQuery mq = eds.createQueryObject(MyQuery.class);
because the return type of EmbeddedDataSource.createQueryObject() is
BaseQuery, not <T extends BaseQuery>.
It must be rewritten to
MyQuery mq = (MyQuery) eds.createQueryObject(MyQuery.class);
or
MyQuery mq = ((DataSource) eds).createQueryObject(MyQuery.class);
Since we can't expect applications to access the EmbeddedDataSource
objects through the DataSource interface, I guess my approach falls
apart. But it was worth a try...
Unless someone knows how to manipulate method signatures when a class
is loaded, or how to make a constructor return a subtype, I think we
are stuck with the current solution.
--
Knut Anders
Re: Are separate JDBC 4.0 versions of the DataSource classes really
needed?
Posted by Rick Hillegas <Ri...@Sun.COM>.
Hi Knut Anders,
I don't understand part of your experiment. The implementation of
createQueryObject() refers to another class, QueryObjectFactory, which
was introduced by JDK 1.6. How did EmbeddedDataSource compile with this
reference?
Thanks,
-Rick
Knut Anders Hatlen wrote:
>Hi,
>
>I started looking at our implementation of JDBC 4.0 data sources when
>I saw Rick updating the documentation with information about using
>Embedded*DataSource40 when running jvm>=1.6. I think it is problematic
>to have this split between pre-JDBC4 data sources and JDBC4 data
>sources for a number of reasons:
>
> - it is confusing for the users to have thirteen different data
> source implementations (EmbeddedSimpleDataSource,
> EmbeddedDataSource, EmbeddedConnectionPoolDataSource,
> EmbeddedXADataSource, EmbeddedDataSource40,
> EmbeddedConnectionPoolDataSource40, EmbeddedXADataSource40,
> ClientDataSource, ClientConnectionPoolDataSource,
> ClientXADataSource, ClientDataSource40,
> ClientConnectionPoolDataSource40, ClientXADataSource40)
>
> - it is difficult to maintain and document properly
>
> - applications that use data sources don't automatically start using
> JDBC 4.0 when upgrading to Derby 10.2
>
> - how should we name the classes when we start implementing JDBC
> 5.0? DataSource40 will be misleading and DataSource50 will only
> increase the confusion (it would give a total of nineteen classes)
>
>For the internal implementation classes, this is not a big problem
>since the users don't see their names, but the DataSource classes are
>in our published API and therefore visible to our users.
>
>The rationale behind adding new classes for the JDBC 4.0 data sources
>was that they contained generic method signatures which wouldn't
>compile under jdk<1.6. The problematic method signatures are
>
> <T> T unwrap(Class<T>)
> <T extends BaseQuery> createQueryObject(Class<T>)
> <T extends BaseQuery> createQueryObject(Class<T>, DataSource)
>
>However, the actual signatures of the compiled methods are
>
> Object unwrap(Class)
> BaseQuery createQueryObject(Class)
> BaseQuery createQueryObject(Class, DataSource)
>
>I tried to put these methods with modified signatures into
>EmbeddedDataSource and removed them from Embedded*DataSource40. To
>make it compile, I had to modify the build.xml script to add an empty
>java.sql.BaseQuery class to the classpath when compiling
>EmbeddedDataSource.
>
>The conclusion from this experiment was: it compiles, it runs under
>jvm1.6 (jdbc40 suite passed without errors), and it runs under jvm1.3,
>jvm1.4 and jvm1.5.
>
>Does anyone see any serious problems with this approach? Although it's
>a dirty hack, I think it is much better than shipping a double set of
>data sources.
>
>
>