Java has added numerous APIs, like Java Database Connectivity (JDBC), to its standard set of libraries. This helps a wider
audience adopt the APIs since optional packages don't need to be bundled with deployments. For groups writing implementations
of these popular APIs, wider adoption makes their offerings more valuable. However, these groups might wish their APIs were
still optional (as opposed to being included with Java's standard library set) when a newer Java version ships with an updated
API that depends on classes and methods unavailable in previous Java versions. Suddenly you must maintain two versions of
the implementation—one that complies with the old API and one that complies with the new API. This is exactly what happened
with the JDBC API in Java 2 Platform, Standard Edition (J2SE) 1.4. Because of changes to the JDBC API, an implementation of
java.sql.Connection cannot compile under both J2SE 1.3 and 1.4.
You might have found yourself in the same predicament as me: I needed to implement JDBC interfaces such as java.sql.Connection, but my code needed to compile under both J2SE 1.3 and 1.4. I didn't want to maintain different source files for J2SE 1.3
and 1.4, so I looked for a better solution.
Unfortunately, the famous Write Once, Run Anywhere (WORA) Java mantra does not include WOCA (Write Once, Compile Anywhere)
if you rely on javac to do your compilation. Luckily, code tricks with the Reflection API and compile tricks with Ant can
come to the rescue. I can have just one set of .java source files and Ant helps me compile it on both J2SE 1.3 and 1.4. Ant lets me modify the .java files on-the-fly to make changes appropriate for the Java version used for compilation. But before I can explain the full
solution, I must explain the full problem.
Two years ago, my company needed a JDBC connection pool but wouldn't pay for one. At the time, we couldn't find a good free
alternative, so we wrote an in-house connection pool. To better track how connections were being used throughout our applications,
we created com.icentris.sql.ConnectionWrapper, which implements java.sql.Connection and some other wrapper classes that implement other java.sql interfaces. The wrapper classes only track database usage in our application and then pass through method calls to the real
JDBC resource.
When J2SE 1.4 came along, we naturally wanted to migrate some of our clients to it so they could benefit from its many enhancements.
But, of course, we still needed to support J2SE 1.3 for clients who saw no reason to upgrade. To our chagrin, ConnectionWrapper and our other JDBC wrapper classes would not compile on J2SE 1.4 without modification. To keep this article simple, I'll
use ConnectionWrapper to demonstrate the techniques I applied to all classes that wouldn't compile under both J2SE 1.3 and 1.4. To comply with
the updated JDBC API, I had to add several methods to ConnectionWrapper, which posed two big problems:
sql classes.
Some code samples can best explain the first problem. Because my ConnectionWrapper wraps a java.sql.Connection, all my examples depend on the realConnection instance variable (in bold) set in the constructor:
Archived Discussions (Read only)
(