How to create an osgi bundle of a maven project which could be easily deployed in Servicemix - osgi-bundle

I have a maven project in my local development environment. when I run :
"mvn clean install", it basically creates a JAR file inside the 'Target' directory.
I have Servicemix up and running. I wanted to know if somehow I could convert this JAR to an OSGI bundle and deploy directly into ServiceMix container.
Thanks.

Just use the maven bundle plugin in your pom, it will embed into the build process and create a bundle of your jar (adds the required OSGi Manifest)
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
</instructions>
</plugin>

Related

Deploy a jar to a wildfly server?

I want to deploy an application packaged in a jar to a wildfly server after maven package phase, and before maven install.
I am using the following plugin in the project pom.xml:
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>2.1.0.Beta1</version>
<configuration>
<hostname>127.0.0.1</hostname>
<port>9990</port>
</configuration>
</plugin>
how to configure this plugin execution?
You need the deploy goal of that plugin. It accepts a filename parameter which you could use to specify the application archive that you want to deploy.
Binding this goal to the deploy phase of Maven will not override other goals being invoked in that phase of the Maven lifecycle. They will continue to run.

Install über jar with maven-shaded-plugin

I have been using maven assembly plugin to create uber jar and deploy to Artifactory.
I switched to maven shade plugin to shade some dependencies.
Now my jar is not deployed during install phase.
In the maven assembly plugin documentation:
When the assembly is created it will use the assemblyId as the
artifact's classifier and will attach the created assembly to the
project so that it will be uploaded into the repository in the install
and deploy phase.
This is not a case for shaded plugin.
How to configure maven pom to deploy uber jar created with shaded plugin?
You have to tell maven-shade-plugin to attach the shaded artifact which can be done via:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jackofall</shadedClassifierName> <!-- Any name that makes sense -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
I also had this problem, where mvn install would build a shaded jar in my target directory but install the non-shaded one to my local Maven repository.
What ultimately proved to be the cause was that I had <finalName> defined in my maven-shade-plugin configuration. That ended up saving the shaded jar under that specific name, while the non-shaded jar took the default jar name which mvn install must look for when it comes time to install. Without <finalName> present, it copied the shaded jar appropriately into the local Maven repository.
With <shadedArtifactAttached>, I could get the shaded jar installed, but only suffixed with shadedClassifierName while the non-shaded jar was present under the normal artifact name, causing libraries dependent on it to pick up the non-shaded jar over the shaded one (which was not what I wanted in this case as I'm building a library with some dependencies shaded).

OSGI nested dependency jars

If I have a OSGI Bundle that has dependency jars nested inside the OSGI Bundle jar, do I need to list those classes in the Import-Package manifest so that I could use them? I would think not.
Also how do I add these dependency jars into my bundle. Do I just put them in the root folder? Do I need to add anything to the manifest file to be able to use these dependencies?
Avoid using Bundle-ClassPath manually. You can use maven-bundle-plugin to solve and embed your third party dependencies like this:
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Export-Package>lumina.extensions.drivers.luminadb</Export-Package>
<Bundle-Activator>lumina.extensions.drivers.luminadb.internal.Activator</Bundle-Activator>
<Embed-Dependency> YOUR ARTIFACT ID HERE </Embed-Dependency>
</instructions>
</configuration>
</plugin>
(...)
</plugins>
For more information visit http://web.ist.utl.pt/ist162500/?p=110
You should not use Import-Package for embedded jars. Instead use Bundle-ClassPath: .,myjar.jar to add the embedded jars to the bundle classpath.

Does Karaf support downloading of transitive dependencies from maven central?

I am trying to use Karaf and I was wondering if it is possible to configure it to pull the transitive dependencies from the Apache Maven Central repository. Without having to use "embedded bundles"
I already know you can pull explicit dependencies, the key part of the the question is the "transitive" ones.
I also know you can use OBR to read from a repository.xml file in a deployed site, but I can't find one for Maven central. A possible answer to the question would be to add the URL, but I can't find it documented anywhere what the repository.xml URL is.
At the moment, my work around is to figure out what the dependencies are and explicitly add them to the
Embedded bundles do not work with the Karaf OSGi blueprint implementation (it just waits for something that won't exist). I also find it ugly to have to do that. Another possible answer I can think of for this question is if there were instructions to create a package that can be deployed to any OSGi container (not just Karaf using KAR files) that contains all the necessary dependencies.
You can use the karaf-maven-plugin to create a feature file from maven dependencies. This will resolve transitive dependencies.
I found a way of doing this in a relatively OSGi standard way using Maven. It uses the maven-dependency-plugin to create a repository that only contains the dependencies that is required on the runtime scope.
Then the maven-bundle-plugin:index goal is executed to create the repository.xml file.
At this point in the target you have a valid obr repository, the maven-assembly-plugin can be used to package it up as needed.
The following pom.xml snippet will do what is required.
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-runtime-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<copyPom>true</copyPom>
<useRepositoryLayout>true</useRepositoryLayout>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>index</id>
<goals>
<goal>index</goal>
</goals>
<phase>verify</phase>
<configuration>
<mavenRepository>${project.build.directory}/dependency</mavenRepository>
</configuration>
</execution>
</executions>
</plugin>
As for Karaf, this a bundle along with its transitive dependencies can be installed without using Karaf's feature.xml using the following commands:
features:install obr
obr:addUrl [location of the OBR repository, can be file:///....]
obr:deploy [symbolicname-of-bundle]
start [symbolicname-of-bundle]
And voila.
Note that this will only load up the bundles that are referenced by the bundle you had specified so if you're using something like Blueprint where in theory it shouldn't know about the other bundles, then you have to explicitly deploy them or create an uber bundle that will contain the bundles you have (like a feature/product)
As far as I know, the best you can do is use Maven to download all the dependancies, and then use the Felix bnd plugin to convert your local (or remote) repository into an OBR that you can use with Karaf.

Maven war plugin

Is it possible to have the maven war plugin output to two different locations? I currently have the following in my pom.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
<configuration>
<webappDirectory>${webappDirectory}</webappDirectory>
</configuration>
</plugin>
This was already existing in the POM for the gwt maven archetype, and I'm guessing this explodes everything into the webappDirectory(which the gwt plugin then uses for it development mode).
When I do a
mvn war:war
It generate a war file for me in the target directory. So, I suspect its a different plugin configuration than the one in my POM (default behaviour?). How do I override this?
I basically want to accomplish the following:
I would like to have two different resource folders "src/resources/a" and "src/resources/b" , and have one of the folders used in the exploded version (currently in my pom) and the other version used when I do a "mvn war:war"
Per this question How to execute maven plugin execution directly from command line?, Maven doesn't use pom configuration when you invoke a plugin directly (e.g. mvn war:war). Your POM config is telling Maven to run the exploded goal when the compile phase is invoked (i.e when you run mvn [phase] where phase is compile or later).
I suggest you investigate using a separate profile for exploded deployment (called eg exploded), with a different configuration of the resources plugin to copy a different resources directory. Then use mvn compile -Pexploded for the exploded version.

Resources