Skip to end of banner
Go to start of banner

Usage of 3rd party libraries in the plugins

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

As from the realization of ticket 

Error rendering macro 'jira' : Unable to locate Jira server for this macro. It may be due to Application Link configuration.
 all the 3rd party libraries that are necessary for the run-time of inspectIT, Commons and CommonsCS plug-ins have to be OSGi based.

The problem with no OSGi libraries

Main problem comes with the class loading on the UI side. As the Eclipse is based on the OSGi platform, all plugins (that are basically bundles in OSGi) have their own class loader. This means that the class A from plugin info.novatec.inspectit.rcp and class B from the info.novatec.inspectit.commons will be loaded with different class loaders. Now, imagine that the both classes are implementing InitializingBean interface from the Spring library. This would require that both plugins specify the needed Spring library as the run-time dependency. When we activate the Spring in the info.novatec.inspectit.rcp plug-in, Spring will search for all implementations of the InitializingBean classes for executing the afterPropertiesSet() method. However, since the InitializingBean class to match is loaded with the class loader of the info.novatec.inspectit.rcp plug-in, class B will not be recognized to implement the interface, because simply the InitializingBean that class B implements will be loaded with the class loader for the info.novatec.inspectit.commons plugin. Same problem appears with other libraries too.

Solution

The solution for the problem is to remove all run-time dependencies from all our plugins and to depend on the OSGi versions of the same libs. So what is the OSGI bundle?

Bundle is an OSGi Alliance term for a module in an OSGi Service Platform. A Bundle is packaged as a regular jar file with additional entries in its manifest. Every jar file in the repository is a valid OSGi bundle and can be deployed as-is into an OSGi Service Platform and the SpringSource dm Server. Bundles in the repository all define the following information:

  • Bundle-Name: the human-readable name of the bundle, for example, "Spring Core".
  • Bundle-SymbolicName: a string that (along with the version information) uniquely identifies the bundle. Symbolic names follow reverse domain-name conventions - for example, "org.springframework.core".
  • Bundle-Version: the version of the bundle, e.g. 2.5.4
  • Export-Package: the packages exported by the bundle. In OSGi only packages that are exported by the bundle are visible to other bundles. Packages that are not exported remain private to the bundle. When searching the repository for bundles providing certain classes or resources, only the exported packages are displayed and searched. Every package is exported with version information, for example, the Spring Core bundle, version 2.5.4 exports version 2.5.4 of the org.springframework.core package.
  • Import-Package: the package-level dependencies of the bundle. These may be optional or mandatory dependencies. Each import specifies the version range it is compatible with (e.g. "version 2.5.0 or higher").

Where to find the budles

Most of the libraries we use currently are available on the SpringSource Enterprise Bundle Repository and can be retrieved by Ivy.

For the libraries that are not available, we need to create bundle on our own. The tool that can help is Bnd. In the attachment of the page there is bnd.jar that can be used to generate the OSGi bundles from the existing jars via command line. 

java -jar bnd.jar wrap [path/to/the/jar/file.jar]

Executing following command will create the jarName.bar file with the MANIFEST.MF file included. There is always the need to manually alter the manifest file after the generation. Please take care of the following:

  1. Make sure that the Bundle-Version: header has the same version number as the library that we try to modify to bundle. This means that MANIFEST.MF for the guava-11.0.1 has to have the Bundle-Version: 11.0.1 header. Note that it is necessary to have a valid OSGi version, meaning that for example Hibernate libraries with 3.5.3-Final are not correct versions for OSGi and have to be changed to 3.5.3.FINAL.
  2. Change the Bundle-SymbolicName: into the format: info.novatec.[artifact name]. This means that the old ivy dependency of 

    <dependency org="org.apache.httpcomponents" name="httpclient" rev="4.1.1" />

    should have the  Bundle-SymbolicName: info.novatec.httpclient in the manually generated bundle. 

  3. Add the Bundle-Vendor: Novatec GmbH to the list of headers

After editing the manifest file, please update the name of the .bar file to the info.novatec.jarName.jar and upload the jar to our Nexus server with the following GAV parameters: 

org = same as in old jar (for example: org.apache.httpcomponents)
name = info.novatec.[artifctname].jar
version = same version as in Bundle-Version header

Specifying dependencies

In the manifest for the Commons, CommonsCS and inspectIT projects we list all required plug-ins as a dependency via Required Plug-ins option.

inspectIT.product

The product file has to contain a list of all needed dependencies from all three mentioned plug-ins. Please keep the list of dependencies there up-to-date.

Ivy organisation

In the settings of the Ivy we have added the SpringSource repositories, so all budles that are available there can be used out of the box with Ivy. For the bundles that we generated we use Nexus as described.

All the OSGi based bundles should always be resolved to the osgi configuration. This should not be changed, because platform target we use in development is relying on the /lib/osgi folders of every plug-in project for the needed bundles.

info.novatec.inspectit.commons and info.novatec.inspectit.commmonscs

The ivy files in this two projects need to have duplicated lists of needed libraries, since this projects are used as normal java project in CMR and as plug-in in inspectIT RCP:

  1. One configuration is osgi and should have all needed bundles
  2. Second configuration is prod and should have normal libraries that will be needed for CMR run

This means that the ivy will define same dependencies twice, one in normal format, one in OSGi format. For example, this is the current look of the ivy.xml in the CommonsCS project:

<?xml version="1.0" encoding="ISO-8859-1"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
	<info organisation="info.novatec.inspectit" module="CommonsCS"/>
	<configurations>
		<conf name="osgi" visibility="private" transitive="false"/>
    	<conf name="prod" visibility="private" transitive="false"/>
    </configurations>
    <!-- note that the manifest file stored in the resource sections needs to be updated to reflect
         any changes to the production libraries (changing of revisions is safe!) -->
    <!-- PLEASE UPDATE THE 3rd PARTY NOTIFICATION LIST IN CMR AND Agent build.xml FOR ANY CHANGE -->
	<!-- IMPORTANT
		 * OSGI based jars are used in inspectIT UI and it is necessary to have the same list of OSGi and normal jars
		 * Any added OSGi jar has to be added in the MANIFEST.MF of this project as a dependency
		 * Any added OSGI jar has to be added to the inspectIT.product as a dependency
	 -->
	<dependencies>
		<!-- OSGi plugins -->
		<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="osgi->compile" />
		<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.lang" rev="2.5.0" conf="osgi->compile" />
		<dependency org="org.springframework" name="org.springframework.core" rev="3.1.0.RELEASE" conf="osgi->compile" />
		<dependency org="org.springframework" name="org.springframework.beans" rev="3.1.0.RELEASE" conf="osgi->compile" />
		<dependency org="org.springframework" name="org.springframework.context" rev="3.1.0.RELEASE" conf="osgi->compile" />
		<dependency org="org.springframework" name="org.springframework.web" rev="3.1.0.RELEASE" conf="osgi->compile" />
		<dependency org="org.springframework" name="org.springframework.asm" rev="3.1.0.RELEASE" conf="osgi->compile" />
		<dependency org="org.springframework" name="org.springframework.expression" rev="3.1.0.RELEASE" conf="osgi->compile" />
		<dependency org="org.springframework" name="org.springframework.aop" rev="3.1.0.RELEASE" conf="osgi->compile" />
		<dependency org="org.aopalliance" name="com.springsource.org.aopalliance" rev="1.0.0" conf="osgi->compile" />
		<dependency org="javax.servlet" name="javax.servlet" rev="3.0.0.v201103241009" conf="osgi->compile" />
		<dependency org="net.sourceforge.cglib" name="com.springsource.net.sf.cglib" rev="2.2.0" conf="osgi->compile" />
		<!-- Original jars for CMR production -->
		<dependency org="commons-logging" name="commons-logging" rev="1.1.1" conf="prod->default" />
		<dependency org="commons-lang" name="commons-lang" rev="2.5" transitive="false" conf="prod->default"/>
		<dependency org="org.springframework" name="spring-core" rev="3.1.0.RELEASE" transitive="false" conf="prod->default"/>
		<dependency org="org.springframework" name="spring-beans" rev="3.1.0.RELEASE" transitive="false" conf="prod->default"/>
		<dependency org="org.springframework" name="spring-context" rev="3.1.0.RELEASE" transitive="false" conf="prod->default"/>
		<dependency org="org.springframework" name="spring-web" rev="3.1.0.RELEASE" transitive="false" conf="prod->default"/>
		<dependency org="org.springframework" name="spring-asm" rev="3.1.0.RELEASE" transitive="false" conf="prod->default"/>
		<dependency org="org.springframework" name="spring-expression" rev="3.1.0.RELEASE" transitive="false" conf="prod->default"/>
		<dependency org="org.springframework" name="spring-aop" rev="3.1.0.RELEASE" transitive="false" conf="prod->default"/>
		<dependency org="aopalliance" name="aopalliance" rev="1.0" transitive="false" conf="prod->default"/>
		<dependency org="cglib" name="cglib-nodep" rev="2.2.2" transitive="false" conf="prod->default"/>
	</dependencies>
</ivy-module>

For the build of the CMR we will use libraries defined in prod configuration and for the build of inspectIT RCP we will use the bundles defined in osgi configuration.

PDE Target Platform

All the OSGi bundles we retrieve via Ivy will be placed in the ${project_loc}/lib/osgi folder. However, when an Eclipse plug-in is run from the Development environment, we need to have those plug-ins available in the Eclipse/plugins/ folder. Since it is complicated for developer to constantly update the plugin folder of Eclipse installation manually, we have created the Target Definition for inspectIT RCP where all needed plug-ins are defined. 

The definition file is inspectit/inspectIT.target and defines four places as the source of required plug-ins for execution:

  1. Commons/lib/osgi folder
  2. CommonsCS/lib/osgi folder
  3. inspectit/lib/osgi folder
  4. Eclipse Indigo update site with plug-ins defined for Eclipse platform and Eclipse Platform SDK
Everything a developer has to do is to set the inspectIT Main Target as target platform. This can be done by opening the inspectIT.target and click on the Set as Target Platform link in the top right corner of the Target definition. Please make sure to perform Ivy > Retrieve on all three plug-in projects so that depending /lib/osgi folders can be used properly.
  • No labels