openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pinaki Poddar (JIRA)" <>
Subject [jira] Commented: (OPENJPA-24) Allow OpenJPA to be extensible
Date Tue, 19 Sep 2006 16:02:24 GMT
    [ ] 
Pinaki Poddar commented on OPENJPA-24:

I had made certain changes for extending OpenJPA with alternative implementaions via ProductDerivations
mechanics. Let me present my understanding of this issue raised orginally by Kevin on this
discussion thread. 

org.apache.openjpa.lib.conf.Configuration carries the properties that determines configurable
behaviour e.g. which concrete PersistenceProvider to create or whether to synchronize the
object schema with that of the database or whether to apply JPA or JDO style mapping primitives
and so on. It is a rich and powerful construct with support for Plugin.  

The purpose of OpenJPA configuration subsystem is to create one such Configuration instance
that is essential for any particular instantiation of the generic kernel known as BrokerFactory.
In fact, BrokerFactory and Configuration enjoy a 1:1 till-detah-do-us-apart sort of relationship.

ProductDerivation, ProductDerivations, ConfigurationProvider, Configurations are abstractions
that participate in creating this Configuration instance. Let us see the roles played by each
of them.

ConfigurationProvider locates where the configuration information is and then reads it. The
information can be in a META-INF/persistence.xml file inside a jar, a file
available in classpath, a -Dxyz=myValue style Java system property, in a Map instance constructed
programatically - the possibilities are not constrained by design. Because OpenJPA -- notwithstanding
its name -- is by design capable of supporting multiple specifications that differs in configuration
grammar -- multiple ConfigurationProvider classes are provided. Given the varied nature of
how configuration information can be made available to the runtime, the basic interface org.apache.openjpa.lib.conf.ConfigurationProvider
provides the discipline of reading configuration from 'global' or 'default' or named resources.
Of course, each concrete implementation would interpret what 'global' or 'default' would mean.
ConfigurationProvider after locating the information resource, reads its content and temporarilly
stores in an internal name-value map. Eventually it pours this content into a Configuration
instance via ConfigurationProvider.setInto(Configuration conf) method. 

ProductDerivation faciliates how Configuration will deal with this content -- which MetaDataFactory
to set, which EntityManagerFactory (or PersistenceManagerFactory) to instantiate as a facade
to the kernel according to active specification and so on. This tunning is accomplished by
hooks during the life of a Configuration before being put to active duty i.e. before a Configuration
instance is constructed, before the content carried by ConfigurationProvider is poured in
Configuration and after a Configuration is set to represent a specification. For example,
the spec-agnostic core configuration implementation ConfigurationImpl nor its derivation OpenJPAConfigurationImpl
declares a plugin for which concrete EntityManagerFactory to construct as a facade. But PersistenceProductDerivation
inserts org.apache.openjpa.persistence.EntityManagerFactoryImpl as the concrete implementation
class for EMF in beforeConfigurationConstruct() hook and adds a EMF-plugin value via beforeConfigurationLoaded()
hook i.e. before ConfigurationProvider pours its content into a Configuration. This allows
the PersistenceProviderImpl to instantiate a org.apache.openjpa.persistence.EntityManagerFactoryImpl
as a facade to BrokerFactory.  

Given that OpenJPA supports an extensive set of configurable parameters it is logical to separate
them into categories such as SPEC, PRODUCT, STORE etc -- and that lead to a host of ProductDerivation
classes each tunning the configuration from its own perspective. org.apache.openjpa.lib.conf.ProductDerivations
is the harness that locates each ProductDerivation available to the system, order them up
sequentially to give a chance to modify Configuration/ConfigurationProvider. ProductDerivations
finds ProductDerivation by looking up one or more "org.apache.openjpa.lib.conf.ProductDerivation"
resources in the classpath and interpreting each line of this simple text-based resource as
a class name for a particular org.apache.openjpa.lib.conf.ProductDerivation implementation.

Configurations hold a bunch of static utility methods to instantiate plugin, pour system properties
into Configuration and so on. I have not looked into this class due dilligence and it may
even be a candidate for being refactored out completely later. 

Given this scheme, the most visible (and mechanical) change is to drive the loading of configuration
data by the ConfigurationProvider via ProductDerivations. It used to be such that different
ConfigurationProvider were activated by Configurations and different ProductDerivation were
activated by ProductDerivations. Now ProductDerivations is the only driver of configuration
subsystem. Each ProductDerivation can supply its own ConfigurationProvider to locate/parse/read
configuration information and supplying a null imply that this ProductDerivation does not
read resource at all. In fact, most of them don't. 

This ProductDerivation-as-driver-of-ConfigurationProvider notion is coded into AbstractProductDerivation.

The other change as outlined by Abe is to move ProductDerivations/ProductDerivation/Configuration
to lib and factor out STORE specifc details in kerenl.OpenJPAProductDerivation. 

With all these machinery and refactoring -- now let us go back to the issue Kevin originally
raised -- how does one extend OpenJPA?
The use case became real when we needed a backward compatibility support for Kodo 4.0. Kodo
4.0 was released few months ago in pre-OpenJPA era. Obviously, a mechanism is needed such
that applications written on Kodo 4.0 but running on Kodo 4.1 based on OpenJPA must be able
to use the old API of kodo.persistence.PersistenceProviderImpl instead of org.apache.... 
In my next post, I will describe how that was done with ProductDerivation, I have to now attend
to booth duty at BEAWorld. 


> Allow OpenJPA to be extensible
> ------------------------------
>                 Key: OPENJPA-24
>                 URL:
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>            Reporter: Kevin Sutter
>         Assigned To: Kevin Sutter
> The current OpenJPA architecture is not extendable to other implementations.  For example,
if somebody wanted to provide their own PersistenceProvider implementation, simply extending
the org.apache.openjpa.PersistenceProviderImpl would not suffice due to the dependencies in
the ConfigurationProviderImpl.  The discussion for this improvement was started on the dev
mailing list.  Once it was determined that there was more to this request than a simple conditional
or two, we decided to open a JIRA report.
> The complete history of this request can be found in the OpenJPA dev mailing list.  The
first message was posted by me (Kevin Sutter) on August 14, titled "Extending the OpenJPA
Implementation".  I will attempt to paraphrase the current state of the problem...
> We have three main players in this issue.  The PersistenceProvider, the ConfigurationProvider,
and the ProductDerivation (along with the various implementations of these interfaces).  Currently,
the ConfigurationProvider is in the lib and is unaware of any specific persistence requirements.
 The ProductDerivation is in the kernel and, unfortunately, is aware of persistence requirements,
specifically the spec and store types.  Abe's postings have indicated that we need to make
these two interfaces more aware of each other and work with each other.  We need to start
with either making ConfigurationProvider more persistence-aware and move it into kernel, or
make ProductDerivations less persistence-aware and move it into lib.  The latter approach
is preferred.
> After we get this re-organization of the base framework complete, we still have a couple
of other issues ot resolve:
>     *  Still need the ability to extend EMF's through a ProductDerivation.  This should
be doable by adding a new PluginValue to indicate what class of EMF to load.
>     *  There is still a question as to whether we will need to provide a custom PersistenceProviderImpl
and ConfigurationProviderImpl pair.  I still think this will be necessary.   And, one of Abe's
posts indicated that this might help with class loading issues when multiple versions of OpenJPA-based
implementations are available in the same system.
> I also posted these questions last Friday.  (Abe has responded with some answers, but
I wanted to get this JIRA report created before trying to paraphrase his answers.)
>     *  You mention in several places about separating away the notion of specs and stores.
 In a general sense, I understand what these are.  But, can you elaborate on how these types
are used in the ConfigurationProvider and ProductDerivation interfaces?
>     * I've moved the ProductDerivation interface to the lib and added the "load" methods
from the ConfigurationProvider (as described in your previous notes).  And, I've started to
clean up the implementations that depend on these interfaces.  But, concerning the implementation
of the load methods...  Now that we need to return a ConfigurationProvider, would you expect
that we just new up a ConfigurationProviderImpl and then just call across to the "load" methods
on the implementation?  Since we want to keep the ProductDerivations stateless, I'm not sure
how else you were expecting to create a ConfigurationProvider to return on these "load" methods.
>     * Now that ConfigurationProvider is bare, the ConfigurationTestConfigurationProvider
doesn't have much function.  I'll need to take a look to see if this is even required any
>     * Can you shed a bit more light on the Configurations class?  It doesn't implement
nor extend any interfaces or classes, but it seems to provide many of the same methods as
ConfigurationProvider, but as statics.  And, it's dependent on having a Provider.  Can you
explain the relationship of this class in the bigger picture and how you think it might be
affected by thes changes?
> That's enough for the initial JIRA report.  We will now track this problem here instead
of the dev mailing list.  Thanks.
> Kevin

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators:
For more information on JIRA, see:


View raw message