Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

 

Code Block
languagehtml/xml
<plugins>
    <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.3.7</version>
        <extensions>true</extensions>
    </plugin>
</plugins>

and changing the packaging type to bundle

 

Code Block
languagehtml/xml
<packaging>bundle</packaging>

The Bundle Plugin will add the required manifest headers to the jar file and calculate the packages that the bundle imports and exports.

Module dependencies

All the dependencies of Taverna's modules also have to be OSGi bundles. First check if the dependency is an OSGi bundle - have a look in the manifest to see if the Bundle-SymbolicName header is present. If the dependency is not a bundle it is worth checking if a later version is.

The SpringSource Bundle Repository contains OSGi bundle versions of many common libraries. Modules in the SpringSource Bundle Repository have different artifactId's to distinguish them from the non OSGi versions, so a dependency declared as

Code Block
languagehtml/xml
<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>

changes to

Code Block
languagehtml/xml
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>com.springsource.org.apache.commons.httpclient</artifactId>
    <version>3.1.0</version>
</dependency>

Embedding dependencies

If an OSGi bundle version of a dependency is not available then it is possible to embed the dependency in the module by using the Private-Package or Embed-Dependency instructions of the Bundle Maven plugin. For example, the RShell Activity has a dependency on rengine and embeds the required packages by adding the Private-Package instruction. 

Code Block
languagehtml/xml
<plugin>
	<groupId>org.apache.felix</groupId>
	<artifactId>maven-bundle-plugin</artifactId>
	<extensions>true</extensions>
	<configuration>
		<instructions>
			<Private-Package>org.rosuda.REngine.*</Private-Package>
		</instructions>
	</configuration>
</plugin>
...
<dependency>
	<groupId>org.rosuda</groupId>
	<artifactId>rengine</artifactId>
	<version>200910</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.rosuda</groupId>
	<artifactId>rserveengine</artifactId>
	<version>200910</version>
	<scope>provided</scope>
</dependency>
Note

Embedded dependencies should have a scope of provided so that the non-OSGi dependency is not added to the build.

If the dependency is required by consumers of a module (perhaps because it used by an API that the module exposes) then the Export-Package can be used. This will embed the dependency but also make it available for other modules by adding the package to the bundles exported packages.

See the Bundle Maven plugin documentation for more information

Creating OSGi services

Taverna 2 services are defined by SPI interfaces. Taverna 3 uses OSGi services so all the SPI definitions (specified in the META-INF/services resource directory) have to be converted to OSGi services.

For example, in Taverna 2 the implementation of the Edits interface in the workflowmodel module is specified in the file META-INF/services/net.sf.taverna.t2.workflowmodel.Edits which the file contains the name of the implementation class

Code Block
titleMETA-INF/services/net.sf.taverna.t2.workflowmodel.Edits
languagenone
net.sf.taverna.t2.workflowmodel.impl.EditsImpl

In Taverna 3 the Edits interface is exported as an OSGi service. The majority of the Taverna 2 SPIs are the same interfaces that need to be registered as services in the OSGi framework. The OSGi services are created and registered using Spring Dynamic Modules for OSGi. So in the above example, the Edits service would be defined in two Spring context files. META-INF/spring/workflowmodel-impl-context.xml creates the implementation bean.

 

Code Block
titleMETA-INF/spring/workflowmodel-impl-context.xml
languagehtml/xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <bean id="editsImpl" class="net.sf.taverna.t2.workflowmodel.impl.EditsImpl" />
 
</beans>

and META-INF/spring/workflowmodel-impl-context-osgi.xml registers the bean as a service with the OSGi framework
Code Block
titleMETA-INF/spring/workflowmodel-impl-context-osgi.xml
languagehtml/xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans.xsd
                                 http://www.springframework.org/schema/osgi
                                 http://www.springframework.org/schema/osgi/spring-osgi.xsd">
 
    <service ref="editsImpl" interface="net.sf.taverna.t2.workflowmodel.Edits" />
 
</beans:beans>

Using OSGi Services

Spring DM is also used for making services available in the OSGi framework available as bean in the spring context. The LocalExecutionService defined in the Taverna Platform requires the Edits service that was registered in the example above. To use the OSGi service two Spring context files are added to the execution-local module. META-INF/spring/execution-local-context-osgi.xml specifies a references to the Edits service.

Code Block
titleMETA-INF/spring/execution-local-context-osgi.xml
languagehtml/xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/osgi"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans.xsd
                                 http://www.springframework.org/schema/osgi
                                 http://www.springframework.org/schema/osgi/spring-osgi.xsd">
 
    <service ref="localExecution" interface="uk.org.taverna.platform.execution.api.ExecutionService"/>
 
    <reference id="workflowModelEdits" interface="net.sf.taverna.t2.workflowmodel.Edits" />
 
</beans:beans>
and META-INF/spring/execution-local-context.xml injects the Edits service into the LocalExecutionService

 

Code Block
titleMETA-INF/spring/execution-local-context.xml
languagehtml/xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <bean id="localExecution" class="uk.org.taverna.platform.execution.impl.local.LocalExecutionService">
        <property name="edits" ref="workflowModelEdits" />
    </bean>
 
</beans>
Specifying Package Providers

It is good practice to specify providers of a package in OSGi so that implementation bundles have the correct version range for the API packages they provide.

For example, the Taverna App Configuration Implementation bundle provides an implementation of the uk.org.taverna.configuration.app package and therefore the import range for the package should only include micro version changes.

Code Block
titlemanifest.mf
Bundle-Name: Taverna App Configuration implementation
Import-Package: javax.xml.bind,org.apache.log4j;version="[1.2,2)",uk.org
 .taverna.commons.profile.xml.jaxb;version="[0.1,1)",uk.org.taverna.conf
 iguration.app;version="[0.1,0.2)"

This is achieved by marking the package import property provide as true in the maven-bundle-plugin configuration.

Code Block
<plugin>
	<groupId>org.apache.felix</groupId>
	<artifactId>maven-bundle-plugin</artifactId>
	<configuration>
		<instructions>
			<Import-Package>uk.org.taverna.configuration.app;provide:=true,*</Import-Package>
		</instructions>
	</configuration>
</plugin>