Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] JPA & OSGi

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

--


Oracle
Shaun Smith | Principal Product Manager, TopLink | +1.905.502.3094
Oracle Fusion Middleware
110 Matheson Boulevard West, Suite 100
Mississauga, Ontario, Canada L5R 3P4

Back to the top