Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I combine WAR packaging and OSGi bundle creation in Maven?

I want to deploy one of my OSGi bundles with a war package structure so it is recognized as a web application by Struts. I use Maven, so I get WAR packaging built-in and I have the Maven bundle-plugin to create the OSGi compatible manifest for me.

The problem is, the two don't work together, so the bundle plugin is not aware that the class files are now in the subfolder classes/ and the bundled jars are in lib/, so it creates a wrong Bundle-classpath header. I could manually add the correct header to my pom.xml, but I'd like to have that don eautomatically. How can I do that?

like image 218
Hanno Fietz Avatar asked Oct 20 '09 07:10

Hanno Fietz


People also ask

Which is a difference between an OSGi bundle and a Java package?

The key difference with OSGi is that a JAR is now all private, adding metadata in the manifest makes it a bundle that can safely share with other bundles. OSGi makes sure violations are detected ahead of time. So, can a bundle be used in place of a jar in a JavaEE application? yes, it is a normal JAR.

What is the purpose of the export package manifest header in OSGi bundle?

This header declares the external dependencies of the bundle that the OSGi Framework uses to resolve the bundle. Specific versions or version ranges for each package can be declared.

What is the use of OSGi bundle?

An OSGi bundle JAR file contains a JAR manifest file. This file contains metadata that enables the OSGi Framework to process the modular aspects of the bundle. Describes the version of the bundle and enables multiple versions of a bundle to be active concurrently in the same framework instance.


1 Answers

One way to (more or less) achieve this is described on OPS4J Wiki page -- "Getting the benefits of maven-bundle-plugin in other project types".

You can configure dependency embedding and Bundle-ClassPath directive in your pom.xml to match the locations used by WAR plugin. The maven-bundle-plugin will then generate correct manifest headers.

The instructions for maven-bundle-plugin might look like this:

<instructions>
    <Bundle-ClassPath>.,WEB-INF/classes,{maven-dependencies}</Bundle-ClassPath>

    <Embed-Directory>WEB-INF/lib</Embed-Directory>
    <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
    <Embed-Transitive>true</Embed-Transitive>
    <!-- ... -->
</instructions>

ETA: When using this approach, I found out two noteworthy things:

  • the bundle plugin will complain about missing WEB-INF directories, because when the manifest goal is executed, the war plugin has not yet created them (it only runs at a later phase)
  • although it doesn't make sense for the actual webapp, the Bundle-ClassPath directive must contain ".", or the bundle plugin will mess up the Import-Packages header. I found this in some JIRA issue via Google, but I can't find the URL anymore.

Other than that it works fine.

like image 90
Pavol Juhos Avatar answered Oct 05 '22 18:10

Pavol Juhos