Core Extensions
Use the extensions/core/ext-core
module to customize and extend core functionalities. This module can include extensions to classes in ep-core
as well as modules that ep-core
depends on, such as ep-settings
or ep-persistence-openjpa
. It can also include new functionalities required for other extension modules.
The ext-core
module has the following structure:
ext-core
src
main
java
com
java
// Extension classes go here
resources
META-INF
conf
ep-core-plugin.xml // Spring definitions and overrides
jpa-persistence.xml // OpenJPA persistence additions and overrides
OSGI-INF
blueprint
springCtx-import.xml // OSGi blueprint descriptor file
pom.xml
OSGi configuration
Cortex runs in an OSGi container. Any library that Cortex uses must be packaged as an OSGi bundle. This section describes how ext-core
is configured for OSGi.
pom.xml
Extension The key OSGi configuration is highlighted in this snippet from the core extension’s pom.xml
:
<artifactId>ext-core</artifactId>
<packaging>bundle</packaging>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<!-- Fragment-Host gives the symbolic name of the core wrapper bundle to attach to. -->
<Fragment-Host>ext-commerce-engine-wrapper</Fragment-Host>
<Import-Package>
!*
</Import-Package>
...
</instructions>
</configuration>
</plugin>
<packaging>bundle</packaging>
The first OSGi configuration data in the POM
is the project’s packaging <packaging>bundle</packaging>
data. With this setting, Maven builds the project as an OSGi bundle. The project still builds into a JAR file, so the project can be used outside of an OSGi setting, which means you can leave this as is even if you are not using the core extension in an OSGi setting.
<artifactId>maven-bundle-plugin</artifactId>
The maven-bundle-plugin
configuration transforms the core extension into a OSGi fragment and tells the fragment to attach to Cortex’s ext-commerce-engine-wrapper
bundle. The extension commerce engine wrapper bundle wraps the core extension in an OSGi bundle. Fragments are treated as part of the host bundles. Relevant definitions of the fragment are merged with the definitions of the host bundle before the host is resolved, as long as the information does not conflict. If possible, fragment dependencies are resolved. However, if the fragment dependencies cannot be resolved, the fragment is not attached to the host bundle. A fragment cannot have its own class loader or bundle activator. It cannot override the information present in the host bundles. Fragments extend bundles with resources, classes, and permitted headers to customize your bundles.
<Import-Package>
The <Import-Package>
element contributes any additional imports to the core bundle. Add !*
in the <Import-Package>
element if you do not want to import anything to the core bundle. If your core extension relies on additional third party libraries, other than the libraries already used by the core bundle, you must list the required packages in the <Import-Package>
instruction. You must also include the manifest header directive value identifying a mandatory resolution type to enable attachment problem logging. For example:
<Import-Package>
org.thirdparty.library.package; resolution:=mandatory,
!*
</Import-Package>
If you do not specify the mandatory resolution, OSGi does not find the third party library package at run time and the fragment fails to attach, however, no error message appears.
springCtx-import.xml
This file provides information about the spring configuration for the extension project to OSGi.
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >
<!-- Let OSGi know the spring configuration of this project. -->
<import resource="../../META-INF/conf/ep-core-plugin.xml" />
</beans>
note
Core extension classes replacing the default core classes, which have the same package structure and class name, do not work with this approach.
If the extension uses third party libraries, the following additional configuration is required:
- Add the third party packages to the
<Import-Package>
element as described in the Extension pom.xml section - If the third-party libraries are OSGi compliant, add the libraries as a dependency and artifact items in the Cortex Webapp
- If the libraries are not OSGi compliant, the libraries must be embedded in the fragment
jpa-persistence.xml
The core extension’s jpa-persistence.xml
file specifies the following:
<persistence-unit name="commerce-persistence-unit">
...
<mapping-file>...</mapping-file>
<class>...</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<validation-mode>NONE</validation-mode>
<properties>
<property name="openjpa.Log" value="slf4j"/>
<property name="openjpa.DetachState" value="loaded(DetachedStateField=true)"/>
</properties>
</persistence-unit>
<mapping-file>
Defines the classpath for new ORM (Object Relational Mapping) metadata mapping files.
<class>
Defines the fully qualified class names of the new persistent classes.
<exclude-unlisted-classes>
Must be set to
true
so that OpenJPA will scan only the classpaths of the listed classes. OSGi does not permit scanning of unlisted clases.<validation-mode>
Must be set to
NONE
, so that OpenJPA does not automatically performJSR 330
validation on objects persisted to the database.<properties>
Must have values as shown above.
openjpa.DetachState
is used during OpenJPA byte code enhancement.Important: Do not add additional properties here. To add or override OpenJPA properties, see Override Persistence Unit Properties
For more information about how to exclude existing ORM mapping files and/or persistent classes, see Exclude references from the Persistence Unit.