Hi Bryan,
Have you taken a look at the OSGi Proof of Concept I'd announced on
the dev and user lists? I repackaged EclipseLink into a set of bundles
and figured some solutions to the classloader issues. We did something
like what you suggested and implemented a service based persistence
provider mechanism. The only real difference between what you
suggested and what we implemented in the POC is that we hid the service
tracker inside javax.persistence.Persistence by making Persistence's
provider resolution strategy pluggable. When in an OSGi environment we
replace the default strategy, which searches the classpath for a
specific XML file containing the names of providers, with one based on
a service tracker.
Of course classloading is the big challenge as a persistence
provider needs access to the classloader of the bundle containing (or
bundle that has visibility of) the Entities, persistence.xml, and any
mapping files. The three approaches supported in the POC are:
1) declaration of persistence units in a bundle manifest which are
detected by EclipseLink and the persistence unit classloader obtained
from the declaring bundle (see org.eclipse.persistence.spi.demo)
2) passing a classloader as a property to createEntityManagerFactory
(see org.eclipse.persistence.spi.classloader.demo)
3) creating an EclipseLink OSGi persistence provider directly and
providing the classloader as a parameter. (see
org.eclipse.persistence.osgi.provider.demo)
We probably need a service tracker approach to JDBC drivers but
haven't got that far yet.
Take a look. I'd love some feedback! Perhaps we can merge your
service based approach to obtaining an EntityManagerFactory with the
service approach we've taken for Providers?
Shaun
Bryan Hunt wrote:
Here are some initial thoughts for discussion ...
Clients could obtain an EntityMangerFactory through an OSGi service.
Something like:
public interface IJPAService
{
EntityManagerFactory createEntityManagerFactory(String unitName);
EntityManagerFactory createEntityManagerFactory(String unitName,
Map<String, String> properties);
}
IJPAService basically replaces javax.persistence.Persistence. The JPA
implementation would register an implementation of the service as an
OSGi service:
public class Activator implements BundleActivator
{
public void start(BundleContext context)
{
context.registerService(IJPAService.class.getName(), new
JPAService(), null);
}
}
public class JPAService implements IJPAService
{
...
}
Clients would access the service using the standard:
public class Activator implements BundleActivator
{
public void start(BundleContext context)
{
ServiceReference ref =
context.getServiceReference(IJPAService.class.getName());
IJPAService service = (IJPAService) context.getService(ref);
}
}
Actually, a service tracker is the proper way to get the service, but
that's not important for this discussion.
This does not prevent a user from using javax.persistence.Persistence.
Should this be allowed, or should that bootstrapping mechanism be
disabled? If we want this to be allowed, it needs to be modified to
not use the context classloader. My preference would be to remove it
from the API, or possibly have it throw UnsupportedOperationException.
The JPA API would be in it's own bundle (javax.persistence ??) separate
from the implementation (org.eclipse.eclipselink.jpa ??).
What should happen if the implementation bundle is stopped and there
are active EntityManagers?
Bryan
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
--
Shaun Smith | Principal Product Manager, TopLink |
+1.905.502.3094
Oracle Fusion Middleware
110 Matheson Boulevard West, Suite 100
Mississauga, Ontario, Canada L5R 3P4
|