Skip to end of metadata
Go to start of metadata

Introduction

The plugins mechanism, thanks to OSGi, allows complete isolation of the plug from the system. Plug-ins can use their own libraries and even other versions of libraries than those installed on the system.

When using a nested library to communicate with other plug-ins / system, problems with class projection may occur. The same class loaded by another classloader (each plugin has a separate classloader) is not compatible and the attempt to project will end with an error.

The solution of such errors requires greater knowledge of OSGi and defining dependencies in the MANIFEST.MFfile.

If in your plugin you want to download the class using Class.forName( "org.apache.axis2.transport.local.LocalTransportSender") from an external library, it MUST be in the plugin, because although this library will be on the system, the plugin will not will have access to it and then recommend the ClassNotFoundException. The same situation is when the system library that we use gets a different class in this way. All libraries should then be connected to the plug-in.

Project configuration

The configuration of nested dependencies must be included in the plugin's pom.xmlfile. We must do the following steps:

  1. define dependence on the library (if we overwrite the system one, we must provide a new version)
  2. configure the maven-bundle-pluginso that our library will be included in the plugin (to the /META-INF/lib directory)

The maven-bundle-plugin is responsible for the process of building the plugin to be compatible with OSGi. In the documentation of this plugin.

pom.xml
	<dependencies>
 
		<!-- We declare our own version apache-poi -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.7</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<configuration>
					<unpackBundle>true</unpackBundle>
					<instructions>
						<!-- we attach all dependencies where groupId=org.apache.poi i artifactId=poi -->
						<Embed-Dependency>*;groupId=org.apache.poi;artifactId=poi</Embed-Dependency>					
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>

The attached dependencies can also be defined simplier:

pom.xml
<!-- simple addition after artifactId -->
<Embed-Dependency>poi</Embed-Dependency>
 
<!-- adding several libraries after artifactId -->
<Embed-Dependency>poi,commons-lang</Embed-Dependency>					

 

The project configured in this way is built into the jar file, which will contain nested libraries in the META-INF/lib directory.

Transitive dependencies

If we use libraries that have their own dependencies, we can use the <Embed-Transitive> true </ Embed-Transitive> statement.

Keep in mind that the <Embed-Dependency> statement is still being checked - the ideal way would be to define it as:

	<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>

however, you should remember to define all system dependencies as <scope>provided</scope>.

Checking the version of the attached library 

The plug-in configured in this way should use Apache's POI library version 3.7. We can easily check this by calling the following code:

  • PlusWorkflow 3.1.0 uses Apache POI 3.9
System.out.println(org.apache.poi.Version.getVersion()); // wypisuje 3.7

Debugging a different version of the library than the one used in the system requires manual change of source, because Eclipse will show sources of the base system version.

Connecting the library from the jar, not the maven dependencies

If you want to connect the library not from maven dependencies but directly from the jar you should copy this jar to src/main/resources in the plugin project, and then add the entry in the plug-in pom file:

pom.xml
	<build>
          <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-ClassPath>.,openedgewp.jar</Bundle-ClassPath>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

It is important that before inputting our jar in Bundle-ClassPath give .,because without this only this jar will go to the classpath plugin (without plugin classes etc.). We add the next jar’s after the semicolon.

Exporting required packages to connected libraries

If during the launch of the plugin with the attached library, a window with the error in the following style pops up:

it means that the library requires additional packages (the package is marked in a red frame -> in this case javax.jws). You should then add the export of this package in the <instructions> section:

<Export-Package>javax.jws</Export-Package>

Altogether it should look as follows:

	<build>
         <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
						<Export-Package>javax.jws</Export-Package>
                        <Bundle-ClassPath>.,openedgewp.jar</Bundle-ClassPath>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

If we would like to export all packages from javax, then we would add javax.*. To add another export, add a new <Export-Package> entry.

  • No labels

1 Comment

  1. Ja użyłem takiego ustawienia Pluginu - biblioteki (jar'y) dodałem do folderu resources

    <plugin>

                    <groupId>org.apache.felix</groupId>

                    <artifactId>maven-bundle-plugin</artifactId>

                    <extensions>true</extensions>

                    <configuration>

                        <instructions>

                            <Export-Package>httpcore,httpclient,google,jsoup</Export-Package>

                            <Bundle-ClassPath>.,httpcore-4.4.4.jar,httpclient-4.5.2.jar,google-http-client-1.22.0.jar,jsoup-1.10.3.jar</Bundle-ClassPath>

                        </instructions>

                    </configuration>

                </plugin>