Java Reference
In-Depth Information
It turns out that it's exactly the classpath that causes problems.
JDBC
driver implemen-
tations rely heavily on
Class.forName()
and
META-INF
services. This sort of reflection
doesn't work in
OSG
i without an explicit package dependency on the driver imple-
mentation. The
DriverManager
only scans the
META-INF
/services folder once, on ini-
tialization, so it might not even find all of the available drivers. (Remember that in
OSG
i things appear on and disappear off the classpath.)
The general experience of using
JDBC
in an
OSG
i environment, therefore, is that
often the
DriverManager
won't recognize your datasource drivers. Even when the
DriverManager
does find the drivers and tries to initialize them, the result is almost
always a
ClassNotFoundException
.
JPA
faces similar problems because it uses similar patterns.
EntityManagerFactories
are constructed reflectively from
META-INF
services by a static
Persistence
class. The
consequence is that the
EntityManagerFactories
can't be found and can't be con-
structed if they
are
found.
Workarounds for both
JPA
and
JDBC
are possible, but they're not pretty. They gen-
erally involve strange little wrappers to bundle-ize
JDBC
and
JPA
providers and register
them by hand with the static
DriverManager
or
Persistence
factory classes. Explicit
dependencies on the exact
JDBC
and
JPA
provider in the manifest of the consuming
code are unavoidable.
What the
META-INF
services pattern is trying to achieve is a loose, service-oriented
coupling between the consuming code and the implementation. The ironic and unin-
tended side effect of this pattern in core
OSG
i is tight coupling and explicit manage-
ment of implementations.
Happily, enterprise
OSG
i offers a first-class services solution. It's natural to register
both
JDBC
and
JPA
providers as
OSG
i services. These can then be looked up from the
Service Registry or injected using Blueprint.
APPLICATION-MANAGED AND CONTAINER-MANAGED PERSISTENCE
With a
JDBC
provider that adheres to the enterprise
OSG
i
JDBC
service specification, an
application is well positioned to access a database using
JDBC
in a clean, service-oriented
way. But few developers use
JDBC
to access databases anymore, unless they're writing a
JPA
implementation!
The
JPA
service specification also allows clean, service-oriented database access, but
it's not as complete a solution as the
JDBC
one. Conventional
JPA
can be used in both
Java
SE
and Java
EE
environments. In Java
SE
environments, the application needs to
do a reasonable amount of work to get hold of the right bits of the
JPA
implementa-
tion, define scopes, handle exceptions, and generally manage the lifecycle of the
JPA
resources. This is described as unmanaged or application-managed
JPA
. In a Java
EE
environment, the container can take over much of this work, significantly reducing
the amount of boilerplate code.
What's offered by the
JPA
service specification is the equivalent of the Java
SE
level
of support. Apache Aries provides extensions to this that bring the support up to the
level of container-managed Java
EE
.