Adding third party jars to Cortex API
Adding third party jars to Cortex API
This tutorial describes how to add third party jars as OSGi dependencies to Cortex.
Adding OSGi Compliant Jars
If the jar is OSGi compliant, add it to cortex-dce-webapp's pom.xml. During the Webapp's start up, this third party jar is included in Cortex and run as an OSGi bundle.
- With a text editor, open Cortex-dce-webapp's pom.xml.
- Add the jar as a dependency:
<dependencies> ... <dependency> <groupId>com.third.party.group</groupId> <artifactId>third-party-jar</artifactId> <version>1.0.0</version> </dependency> ... </dependencies>
- Add the jar as an artifact item.
<plugin> <groupId>org.apache.maven.plugins</groupId> ... <artifactItems> ... <artifactItem> <groupId>com.third.party.group</groupId> <artifactId>third-party-jar</artifactId> </artifactItem> ... </artifactItems> ... </plugin>
- Rebuild Cortex-dce-webapp and run Cortex Webapp.
Adding non-OSGi Compliant Jars
Adding a non-OSGi compliant jar to Cortex will display "could not start bundle... missing requirements" exceptions during start up. For example:
... RELOS: 2246 [ main] ERROR los.webapp.osgi.impl.JarBundleLoaderImpl - Could not start bundle com.elasticpath.rest.integration.epcommerce.ep-resource-purchases-epcommerce org.osgi.framework.BundleException: Unresolved constraint in bundle com.elasticpath.rest.integration.epcommerce.ep-resource-purchases-epcommerce [8]: Unable to resolve 8.0: missing requirement [8.0] osgi.wiring.package; (osgi.wiring.package=com.elasticpath.commons.beanframework) [caused by: Unable to resolve 88.0: missing requirement [88.0] osgi.wiring.package; (osgi.wiring.package=org.apache.bval) [caused by: Unable to resolve 14.0: missing requirement [14.0] osgi.wiring.package; (osgi.wiring.package=javax.validation)]] ... RELOS: 2335 [ main] ERROR los.webapp.osgi.impl.JarBundleLoaderImpl - Could not start bundle org.apache.bval.org.apache.bval.bundle org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.bval.org.apache.bval.bundle [14]: Unable to resolve 14.0: missing requirement [14.0] osgi.wiring.package; (osgi.wiring.package=javax.validation) ... RELOS: 2449 [ main] ERROR los.webapp.osgi.impl.JarBundleLoaderImpl - Could not start bundle com.elasticpath.rest.integration.epcommerce.ep-resource-slots-epcommerce org.osgi.framework.BundleException: Unresolved constraint in bundle com.elasticpath.rest.integration.epcommerce.ep-resource-slots-epcommerce [32]: Unable to resolve 32.0: missing requirement [32.0] osgi.wiring.package; (osgi.wiring.package=com.elasticpath.commons.constants) [caused by: Unable to resolve 88.0: missing requirement [88.0] osgi.wiring.package; (osgi.wiring.package=org.apache.bval) [caused by: Unable to resolve 14.0: missing requirement [14.0] osgi.wiring.package; (osgi.wiring.package=javax.validation)]] ... RELOS: 2567 [ main] ERROR los.webapp.osgi.impl.JarBundleLoaderImpl - Could not start bundle com.elasticpath.rest.integration.epcommerce.ep-resource-carts-epcommerce org.osgi.framework.BundleException: Unresolved constraint in bundle com.elasticpath.rest.integration.epcommerce.ep-resource-carts-epcommerce [38]: Unable to resolve 38.0: missing requirement [38.0] osgi.wiring.package; (osgi.wiring.package=com.elasticpath.common.dto) [caused by: Unable to resolve 88.0: missing requirement [88.0] osgi.wiring.package; (osgi.wiring.package=org.apache.bval) [caused by: Unable to resolve 14.0: missing requirement [14.0] osgi.wiring.package; (osgi.wiring.package=javax.validation)]] ... <continued for other resources referencing javax.validation>
There are three ways to mitigate this issue:
Find an OSGi Compliant Version of the Jar
Find an OSGi compliant version of the third party jar. There are several sources to finding it; two good sources are listed below.
- http://ebr.springsource.com/repository/app/ - a repository of OSGi compliant jars used for building Spring applications
- http://mvnrepository.com - the central maven repository
Make the Jar OSGi Compliant
Tools are available to make a jar OSGi compliant.The most popular tool is BND:
http://www.aqute.biz/Bnd/Bnd
BND's wrap command takes an existing jar, guesses the right headers for the jar's manifest, and creates a new OSGi bundle jar.
bnd wrap osgi.jar *.jar
Use OSGi Framework Properties
- org.osgi.framework.bootdelegation - allows us to specify, at a global framework level, a list of packages to implicitly make available to all bundles in the framework. There is no need to declare the classes in the Import-Package headers of the bundles using them.
- org.osgi.framework.system.packages.extra - allows us to add to the list of packages exported by the System Bundle (bundle id 0). Once exported, the packages are then available to the other bundles in the framework, but only if they are explicitly imported in the bundle's Import-Package headers.
- With a text editor, open cortex-dce-webapp/src/main/resources/spring/applicationContext.xml
- Add the third party jar to the org.osgi.framework.bootdelegation list:cortex-dce-webapp applicationContext.xml
... <bean name="osgiFrameworkProperties" class="java.util.HashMap"> <constructor-arg> <map> ... <entry key="org.osgi.framework.bootdelegation" value="org.w3c.dom.ranges, org.w3c.dom.traversal, org.w3c.dom.bootstrap, org.w3c.dom.events, org.w3c.dom.ls, javax.xml.parsers, sun.reflect, weblogic.xml.jaxp, org.apache.xerces.jaxp, javax.inject, javax.net.ssl, javax.validation, javax.validation.bootstrap, javax.validation.spi, javax.validation.metadata, javax.management, oracle.sql"/commerce-legacy/> </map> </constructor-arg> ... </bean>
- Add the third party jar to the org.osgi.framework.system.packages.extra list:cortex-dce-webapp applicationContext.xml
... <bean name="osgiFrameworkProperties" class="java.util.HashMap"> <constructor-arg> <map> ... <entry key="org.osgi.framework.system.packages.extra" value="javax.inject, javax.net.ssl, javax.validation, javax.validation.bootstrap, javax.validation.constraints, javax.validation.groups, javax.validation.metadata, javax.validation.spi, javax.servlet; javax.servlet.http;version=2.5, sun.reflect, org.slf4j; org.slf4j.spi; org.slf4j.helpers;version=1.7.5"/commerce-legacy/> ... </bean>
- Add the jar artifact as a dependency under Cortex-dce-webapp pom.xml:
<dependencies> ... <dependency> <groupId>com.third.party.group</groupId> <artifactId>third-party-jar</artifactId> <version>1.0.0</version> </dependency> ... </dependencies>
- Rebuild cortex-dce-webapp and run theCortex Webapp
If your bundle has an Import-Package declaration for a jar, simply declaring the bundle in org.osgi.framework.bootdelegation will not be enough since it only makes the package available in the class loader. You must also declare the package in the org.osgi.framework.system.packages.extra for the bundle to be differentiated from the system bundle.
The general rule is use org.osgi.framework.bootdelegation when you don't have control over the manifest of the problematic bundle and you don't mind exposing the package to every other bundle. Use org.osgi.framework.system.packages.extra when a bundle imports a package and you expect the system bundle (not another bundle) to provide it.
How to tell if your dependency is OSGi compliant
Expand the dependency's jar file, and find the META-INF/MANIFEST.MF file. Non-OSGi compliant jars don't have bundle key/value tags inside the manifest, while OSGi compliant jars do.
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: hardy Build-Jdk: 1.5.0_20
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Bundle Plugin Built-By: hen Build-Jdk: 1.5.0_22 Implementation-Build: UNKNOWN_BRANCH@r??????; 2011-11-09 22:58:07-0800 Implementation-Title: Commons Lang Implementation-Vendor: The Apache Software Foundation Implementation-Vendor-Id: org.apache Implementation-Version: 3.1 Specification-Title: Commons Lang Specification-Vendor: The Apache Software Foundation Specification-Version: 3.1 X-Compile-Source-JDK: 1.5 X-Compile-Target-JDK: 1.5 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Include-Resource: templates/release-notes.vm=src/main/resources/templa tes/release-notes.vm,META-INF/LICENSE.txt=LICENSE.txt,META-INF/NOTICE .txt=NOTICE.txt Bnd-LastModified: 1320908300777 Export-Package: org.apache.commons.lang3.event;version="3.1",org.apach e.commons.lang3.mutable;version="3.1",org.apache.commons.lang3.tuple; version="3.1",org.apache.commons.lang3.time;version="3.1",org.apache. commons.lang3.concurrent;version="3.1",org.apache.commons.lang3.text. translate;version="3.1",org.apache.commons.lang3.text;version="3.1",o rg.apache.commons.lang3.math;version="3.1",org.apache.commons.lang3;v ersion="3.1",org.apache.commons.lang3.exception;version="3.1",org.apa che.commons.lang3.reflect;version="3.1",org.apache.commons.lang3.buil der;version="3.1" Bundle-Version: 3.1.0 Bundle-Name: Commons Lang Bundle-Description: Commons Lang, a package of Java utility classes fo r the classes that are in java.lang's hierarchy, or are considered t o be so standard as to justify existence in java.lang. Private-Package: templates Bundle-DocURL: http://commons.apache.org/lang/ Bundle-Vendor: The Apache Software Foundation Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.apache.commons.lang3 Tool: Bnd-1.15.0