HHH-8112 osgi devguide
This commit is contained in:
parent
8f07d59243
commit
2f83a23958
|
@ -50,6 +50,12 @@
|
|||
<surname>Badner</surname>
|
||||
</personname>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Brett</firstname>
|
||||
<surname>Meyer</surname>
|
||||
</personname>
|
||||
</author>
|
||||
|
||||
<othercredit>
|
||||
<personname>
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
<xi:include href="JMX.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||
<xi:include href="Envers.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||
<xi:include href="chapters/multitenancy/Multi_Tenancy.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||
<xi:include href="chapters/osgi/OSGi.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||
<xi:include href="appendix-Configuration_Properties.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||
<xi:include href="appendices/legacy_criteria/Legacy_Criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||
</book>
|
||||
|
|
|
@ -0,0 +1,402 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xl="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<info>
|
||||
<title>OSGi</title>
|
||||
<abstract>
|
||||
<para>
|
||||
The Open Services Gateway initiative (OSGi) specification describes a dynamic, modularized system. "Bundles"
|
||||
(components) can be installed, activated, deactivated, and uninstalled during runtime, without requiring
|
||||
a system restart. OSGi frameworks manage bundles' dependencies, packages, and classes. The framework
|
||||
is also in charge of ClassLoading, managing visibility of packages between bundles. Further, service
|
||||
registry and discovery is provided through a "whiteboard" pattern.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
OSGi environments present numerous, unique challenges. Most notably, the dynamic nature of available
|
||||
bundles during runtime can require significant architectural considerations. Also,
|
||||
architectures must allow the OSGi-specific ClassLoading and service registration/discovery.
|
||||
</para>
|
||||
</abstract>
|
||||
</info>
|
||||
|
||||
<section>
|
||||
<title>OSGi Specification and Environment</title>
|
||||
|
||||
<para>
|
||||
Hibernate targets the OSGi 4.3 spec or later. It was necessary to start with 4.3, over 4.2, due to our
|
||||
dependency on OSGi's <literal>BundleWiring</literal> for entity/mapping scanning.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Hibernate supports three types of configurations within OSGi.
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<firstterm>Container-Managed JPA</firstterm>: <xref linkend="osgi-managed-jpa"/>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<firstterm>Unmanaged JPA</firstterm>: <xref linkend="osgi-unmanaged-jpa"/>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<firstterm>Unmanaged Native</firstterm>: <xref linkend="osgi-unmanaged-native"/>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>hibernate-osgi</title>
|
||||
|
||||
<para>
|
||||
Rather than embed OSGi capabilities into hibernate-core, hibernate-entitymanager, and sub-modules,
|
||||
hibernate-osgi was created. It's purposefully separated, isolating all OSGi dependencies. It provides an
|
||||
OSGi-specific ClassLoader (aggregates the container's CL with core and entitymanager CLs), JPA persistence
|
||||
provider, SF/EMF bootstrapping, entities/mappings scanner, and service management.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="osgi-managed-jpa">
|
||||
<title>Container-Managed JPA</title>
|
||||
|
||||
<para>
|
||||
The Enterprise OSGi specification includes container-managed JPA. The container is responsible for
|
||||
discovering persistence units and creating the <literal>EntityManagerFactory</literal> (one EMF per PU).
|
||||
It uses the JPA provider (hibernate-osgi) that has registered itself with the OSGi
|
||||
<literal>PersistenceProvider</literal> service.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Quickstart tutorial project, demonstrating a container-managed JPA client bundle:
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/tree/master/documentation/src/main/docbook/quickstart/tutorials/osgi/managed-jpa">managed-jpa</link>
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Client bundle imports</title>
|
||||
<para>
|
||||
Your client bundle's manifest will need to import, at a minimum,
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<literal>javax.persistence</literal>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>org.hibernate.proxy</literal> and <literal>javassist.util.proxy</literal>, due to
|
||||
Hibernate's ability to return proxies for lazy initialization
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>JPA 2.1</title>
|
||||
|
||||
<para>
|
||||
No Enterprise OSGi JPA container currently supports JPA 2.1 (the spec is not yet released). For
|
||||
testing, the managed-jpa example makes use of
|
||||
<link xl:href="https://github.com/brmeyer/aries/tree/jpa21">Brett's fork of Aries</link>. To work
|
||||
with Hibernate 4.3, clone the fork and build Aries JPA.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>DataSource</title>
|
||||
<para>
|
||||
Typical Enterprise OSGi JPA usage includes a DataSource installed in the container. The client
|
||||
bundle's <literal>persistence.xml</literal> uses the DataSource through JNDI. For an example,
|
||||
see the QuickStart's DataSource:
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/datasource-h2.xml">datasource-h2.xml</link>
|
||||
The DataSource is then called out in
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/managed-jpa/src/main/resources/META-INF/persistence.xml">
|
||||
persistence.xml's</link> <literal>jta-data-source</literal>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Bundle Ordering</title>
|
||||
<para>
|
||||
Hibernate currently requires fairly specific bundle activation ordering. See the managed-jpa
|
||||
QuickStart's
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/managed-jpa/features.xml">features.xml</link>
|
||||
for the best supported sequence.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Obtaining an EntityManger</title>
|
||||
<para>
|
||||
The easiest, and most supported, method of obtaining an <literal>EntityManager</literal> utilizes OSGi's
|
||||
<literal>blueprint.xml</literal>. The container takes the name of your persistence unit, then injects
|
||||
an <literal>EntityManager</literal> instance into your given bean attribute. See the
|
||||
<literal>dpService</literal> bean in the managed-jpa QuickStart's
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/managed-jpa/src/main/resources/OSGI-INF/blueprint/blueprint.xml">blueprint.xml</link>
|
||||
for an example.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="osgi-unmanaged-jpa">
|
||||
<title>Unmanaged JPA</title>
|
||||
|
||||
<para>
|
||||
Hibernate also supports the use of JPA through hibernate-entitymanager, unmanaged by the OSGi
|
||||
container. The client bundle is responsible for managing the EntityManagerFactory and EntityManagers.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Quickstart tutorial project, demonstrating an unmanaged JPA client bundle:
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/tree/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-jpa">unmanaged-jpa</link>
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Client bundle imports</title>
|
||||
<para>
|
||||
Your client bundle's manifest will need to import, at a minimum,
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<literal>javax.persistence</literal>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>org.hibernate.proxy</literal> and <literal>javassist.util.proxy</literal>, due to
|
||||
Hibernate's ability to return proxies for lazy initialization
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
JDBC driver package (example: <literal>org.h2</literal>)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>org.osgi.framework</literal>, necessary to discover the EMF (described below)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Bundle Ordering</title>
|
||||
<para>
|
||||
Hibernate currently requires fairly specific bundle activation ordering. See the unmanaged-jpa
|
||||
QuickStart's
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-jpa/features.xml">features.xml</link>
|
||||
for the best supported sequence.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Obtaining an EntityMangerFactory</title>
|
||||
<para>
|
||||
hibernate-osgi registers an OSGi service, using the JPA <literal>PersistenceProvider</literal> interface
|
||||
name, that bootstraps and creates an <literal>EntityManagerFactory</literal> specific for OSGi
|
||||
environments. It is VITAL that your EMF be obtained through the service, rather than creating it
|
||||
manually. The service handles the OSGi ClassLoader, discovered extension points, scanning, etc. Manually
|
||||
creating an <literal>EntityManagerFactory</literal> is guaranteed to NOT work during runtime!
|
||||
</para>
|
||||
<para>
|
||||
For an example on how to discover and use the service, see the unmanaged-jpa
|
||||
QuickStart's
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-jpa/src/main/java/org/hibernate/osgitest/HibernateUtil.java">HibernateUtil.java</link>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="osgi-unmanaged-native">
|
||||
<title>Unmanaged Native</title>
|
||||
|
||||
<para>
|
||||
Native Hibernate use is also supported. The client bundle is responsible for managing the
|
||||
SessionFactory and Sessions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Quickstart tutorial project, demonstrating an unmanaged native client bundle:
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/tree/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-native">unmanaged-native</link>
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Client bundle imports</title>
|
||||
<para>
|
||||
Your client bundle's manifest will need to import, at a minimum,
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<literal>javax.persistence</literal>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>org.hibernate.proxy</literal> and <literal>javassist.util.proxy</literal>, due to
|
||||
Hibernate's ability to return proxies for lazy initialization
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
JDBC driver package (example: <literal>org.h2</literal>)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>org.osgi.framework</literal>, necessary to discover the SF (described below)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>org.hibernate.*</literal> packages, as necessary (ex: cfg, criterion, service, etc.)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Bundle Ordering</title>
|
||||
<para>
|
||||
Hibernate currently requires fairly specific bundle activation ordering. See the unmanaged-native
|
||||
QuickStart's
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-native/features.xml">features.xml</link>
|
||||
for the best supported sequence.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Obtaining an SessionFactory</title>
|
||||
<para>
|
||||
hibernate-osgi registers an OSGi service, using the <literal>SessionFactory</literal> interface
|
||||
name, that bootstraps and creates an <literal>SessionFactory</literal> specific for OSGi
|
||||
environments. It is VITAL that your SF be obtained through the service, rather than creating it
|
||||
manually. The service handles the OSGi ClassLoader, discovered extension points, scanning, etc. Manually
|
||||
creating an <literal>SessionFactory</literal> is guaranteed to NOT work during runtime!
|
||||
</para>
|
||||
<para>
|
||||
For an example on how to discover and use the service, see the unmanaged-native
|
||||
QuickStart's
|
||||
<link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-native/src/main/java/org/hibernate/osgitest/HibernateUtil.java">HibernateUtil.java</link>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Optional Modules</title>
|
||||
|
||||
<para>
|
||||
The <link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-native">unmanaged-native</link>
|
||||
QuickStart project demonstrates the use of optional Hibernate modules. Each module adds additional
|
||||
dependency bundles that must first be activated
|
||||
(see <link xl:href="https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/main/docbook/quickstart/tutorials/osgi/unmanaged-native/features.xml">features.xml</link>).
|
||||
As of ORM 4.2, Envers is fully supported. Support for C3P0, Proxool, EhCache, and Infinispan were added in
|
||||
4.3, however none of their 3rd party libraries currently work in OSGi (lots of ClassLoader problems, etc.).
|
||||
We're tracking the issues in JIRA.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Extension Points</title>
|
||||
|
||||
<para>
|
||||
Multiple contracts exist to allow applications to integrate with and extend Hibernate capabilities. Most
|
||||
apps utilize JDK services to provide their implementations. hibernate-osgi supports the same
|
||||
extensions through OSGi services. Implement and register them in any of the three configurations.
|
||||
hibernate-osgi will discover and integrate them during EMF/SF bootstrapping. Supported extension points
|
||||
are as follows. The specified interface should be used during service registration.
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<literal>org.hibernate.integrator.spi.Integrator</literal> (as of 4.2)
|
||||
</listitem>
|
||||
<listitem>
|
||||
<literal>org.hibernate.boot.registry.selector.StrategyRegistrationProvider</literal> (as of 4.3)
|
||||
</listitem>
|
||||
<listitem>
|
||||
<literal>org.hibernate.metamodel.spi.TypeContributor</literal> (as of 4.3)
|
||||
</listitem>
|
||||
<listitem>
|
||||
JTA's <literal>javax.transaction.TransactionManager</literal> and
|
||||
<literal>javax.transaction.UserTransaction</literal> (as of 4.2), however these are typically
|
||||
provided by the OSGi container.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The easiest way to register extension point implementations is through a <literal>blueprint.xml</literal>
|
||||
file. Add <literal>OSGI-INF/blueprint/blueprint.xml</literal> to your classpath. Envers' blueprint
|
||||
is a great example:
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Example extension point registrations in blueprint.xml</title>
|
||||
<programlisting role="XML"><xi:include href="extras/extension_point_blueprint.xml" parse="text"/></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Extension points can also be registered programmatically with
|
||||
<literal>BundleContext#registerService</literal>, typically within your
|
||||
<literal>BundleActivator#start</literal>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Caveats</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Technically, multiple persistence units are supported by Enterprise OSGi JPA and unmanaged
|
||||
Hibernate JPA use. However, we cannot currently support this in OSGi. In Hibernate 4, only one
|
||||
instance of the OSGi-specific ClassLoader is used per Hibernate bundle, mainly due to heavy use of
|
||||
static TCCL utilities. We hope to support one OSGi ClassLoader per persistence unit in
|
||||
Hibernate 5.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Scanning is supported to find non-explicitly listed entities and mappings. However, they MUST be
|
||||
in the same bundle as your persistence unit (fairly typical anyway). Our OSGi ClassLoader only
|
||||
considers the "requesting bundle" (hence the requirement on using services to create EMF/SF),
|
||||
rather than attempting to scan all available bundles. This is primarily for versioning
|
||||
considerations, collision protections, etc.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Currently, Hibernate OSGi is primarily tested using Apache Karaf and Apache Aries JPA. Additional
|
||||
testing is needed with Equinox, Gemini, and other container providers.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Hibernate ORM has many dependencies that do not currently provide OSGi manifests.
|
||||
The QuickStart tutorials make heavy use of 3rd party bundles (SpringSource, ServiceMix) or the
|
||||
<literal>wrap:...</literal> operator.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
As previously mentioned, bundle activation is currently order specific. See the QuickStart
|
||||
tutorials' <literal>features.xml</literal> for example sequences.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The environment should be considered STATIC. Hibernate currently does not support the ability
|
||||
to dynamically add and remove client bundles during runtime. Doing so is typically
|
||||
catastrophic. We hope to better support at least partially-dynamic environments in
|
||||
Hibernate 5.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
No Enterprise OSGi JPA container currently supports JPA 2.1 (the spec is not yet released). For
|
||||
testing, the managed-jpa example makes use of
|
||||
<link xl:href="https://github.com/brmeyer/aries/tree/jpa21">Brett's fork of Aries</link>. To work
|
||||
with Hibernate 4.3, clone the fork and build Aries JPA.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
</chapter>
|
|
@ -0,0 +1,11 @@
|
|||
<blueprint default-activation="eager"
|
||||
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<bean id="integrator" class="org.hibernate.envers.event.spi.EnversIntegrator" />
|
||||
<service ref="integrator" interface="org.hibernate.integrator.spi.Integrator" />
|
||||
|
||||
<bean id="typeContributor"
|
||||
class="org.hibernate.envers.internal.entities.TypeContributorImpl" />
|
||||
<service ref="typeContributor" interface="org.hibernate.metamodel.spi.TypeContributor" />
|
||||
|
||||
</blueprint>
|
Loading…
Reference in New Issue