DataNucleus is an extensible persistence tool. The DataNucleus Core persistence engine allows the user to plug in many user extensions which will contribute to augment the numerous persistence aspects faced by the Object/Datastore mapping. Plugins are loaded by a plugin manager which uses a registry mechanism, inspecting jars in the CLASSPATH.
These plugins are defined in OSGi format. This format relies on there being a set of extension-points where DataNucleus can be extended, and then adding extensions for each of these points. The format means that with very little effort any user can provide their own DataNucleus plugins and have them available very quickly. In short, the three steps necessary for creating a DataNucleus plugin are
A minimum META-INF/MANIFEST.MF for a plugin jar should look like this
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: myplugin Bundle-SymbolicName: org.datanucleus.myplugin Bundle-Version: 1.0.0 Bundle-Vendor: My Company
Each plugin extension has attributes. If you want to override an extension that is included in DataNucleus itself then you need to specify the priority attribute, setting it to an integer (the default plugin has priority=0, so set to higher than this to override it).
If you write a DataNucleus plugin and you either want it to be included in the DataNucleus distribution, or want it to be listed here then please contact us via the DataNucleus Forum
Non managed environment is a runtime environment where DataNucleus runs and plug-ins are not managed by a container. In this environment the plug-in discovery and lifecycle is managed by DataNucleus.
There is a 1 to N instance relationship from DataNucleus to a plug-in per PMF. More exactly, if only one PMF exists, there is only one Plug-in instance for a Connection Pool Plug-in, and if "N" PMF exist, there are "N" Plug-in instances for a Connection Pool Plug-in.
Standard Java runtimes and J2EE containers are considered non managed environments. In non managed environments there is no lifecycle itself of plug-ins. Extensions implemented by plug-ins are instantiated on demand and terminated on PMF closing, PM closing or in another form depending in what the extension is used for.
Managed environment is a runtime environment where DataNucleus plug-ins are managed by a container. The discovery, registry and lifecycle of plug-ins are controlled by the container. There is no plug-in instance relationship from DataNucleus to a plug-in regarding PMF instances. In managed environments, there is only one plug-in instance for one or "N" PMFs. Again, this is managed by the container.
DataNucleus supports OSGi containers as managed environment. In OSGi managed environments plug-in lifecycle is determined by OSGi specification. Once activated, a plug-in is only stopped when the OSGi container finishes its execution, or the plug-in is stopped by an OSGi command.
DataNucleus has mechanism that allows extending its persistence engine while not coupling the DataNucleus engine to the extensions. This mechanism is known as "Extension Points", which are well defined interfaces that allows the extension of certain aspects of DataNucleus in a dynamic and consistent model. The "Extensions" are the implementation of Extension Points that are registered in a PluginRegistry and used by DataNucleus Core or other DataNucleus Plug-ins. A plugin owns an Extension. The behaviour is defined below :-
Plugins can make use of existing persistence properties defined by "core" etc. They can also add on their own persistence properties. They define these in the plugin.xml. Let's take an example
<!-- PERSISTENCE PROPERTIES --> <extension point="org.datanucleus.persistence_properties"> <persistence-property name="datanucleus.rdbms.query.fetchDirection" value="forward" validator="org.datanucleus.store.rdbms.RDBMSPropertyValidator"/> </extension>
So here we have a property defined in the "store.rdbms" plugin which defines a persistence property org.datanucleus.rdbms.query.fetchDirection with a default value of forward and with values validated by the class org.datanucleus.store.rdbms.RDBMSPropertyValidator. This means that when we instantiate a PMF/EMF we automatically get that property defined with value "forward", and if we provide it ourselves we override this default. We do the same with any properties we want in our own plugins.
In order to avoid conflicts between different property names that can be set in the PMF and to have a consistent naming schema for properties, the following recommendations should be applied.
Naming the persistence property name should be prefixed by the plug-in id. Example:
Plugin: org.datanucleus.myplugin1 Property: myprop1
The persistence property should look like datanucleus.myplugin1.myprop1.
If an extension point defines a new persistence configuration, the property name should be prefixed by the extension-point id. Example:
Extension-Point id: org.datanucleus.myplugin2.myextensionpoint2 Property: myprop2
The persistence property should look like datanucleus.myplugin2.myextensionpoint2.myprop2.
Another form of persistence configuration could happen if multiple Extension-Points uses the same information. In this case an abstraction of the plug-in id and extension point id could be used, as the following example. However, make sure to use this naming schema only when absolutelly necessary.
Extension-Point id: org.datanucleus.myplugin3.myextensionpoint3 Extension-Point id: org.datanucleus.yourplugin3.yourextensionpoint4 Extension-Point id: org.datanucleus.theirplugin4.theirextensionpoint5 Property: myprop345
The persistence property should look like datanucleus.somepluginXXXX.someextensionpointYYYY.myprop345. Alternativelly, the PMF property could also look like datanucleus.myplugin3.myextensionpoint3.myprop345
It's a goal of the DataNucleus project to seamless integrate to all major 3rd party products used by the DataNucleus community. In addition to the plugins above it also provides plugins for the Eclipse IDE. All plugins can be downloaded here.