How to embed a library JAR in an OSGi bundle using Tycho - maven

I am using Maven with the Tycho plugin to build my OSGi bundles.
In one of my bundles, I use the facebook API through the restfb-1.7.0.jar library.
For now, it is directly placed on the classpath (in Eclipse) and embedded in the effective OSGi bundle jar file with following build.properties configuration:
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
lib/restfb-1.7.0.jar
Now I would like to have this restfb lib downloaded from Maven (e.g. as dependency) and embedded into my OSGi bundle jar. Is it possible with Maven/Tycho? How?

You need the following configuration to embed a JAR into an OSGi plugin with Tycho:
In the pom.xml, configure the copy goal of the maven-dependency-plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-libraries</id>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<item>
<groupId>com.restfb</groupId>
<artifactId>restfb</artifactId>
<version>1.7.0</version>
</item>
</artifactItems>
<outputDirectory>lib</outputDirectory>
<stripVersion>true</stripVersion>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Edit the MANIFEST.MF to have the library added to the OSGi bundle classpath
Bundle-ClassPath: ., lib/restfb.jar
Edit the build.properties to have the library included in the JAR packaged by Tycho
bin.includes = META-INF/,\
.,\
lib/restfb.jar

I think what you would want is to have a dependency in the POM with the compile time scope like the example below: use the correct artifact and version info to get the item you want. you should investigate the dependencies section of the maven ref for poms
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>compile</scope>
</dependency>

Related

How do I include third party libraries in openLiberty maven build

I'm currently running a PoC with open Liberty and I'm having a bit of trouble with libraries.
The short of it is our project has a few third party jars that need to be included as libraries, but I can't figure out how to include them when I run mvn install in my Open Liberty project.
I'm trying to configure them in server.xml as follows:
<library id="MyLib" name="My Libraries">
<fileset dir="${server.config.dir}/myLib/" includes="*.jar" id="myLib"/>
</library>
I had hoped they would be picked up by the maven build, but obviously not.
What steps do I need to take to make make sure my library jars are placed in the correct place when running mvn install?
First of all, I will recommend the easiest approach which is packaging the libraries inside of your application (no server.xml <library> config needed this way). If you are using the maven-war-plugin, then any non-provided dependencies will automatically end up in WEB-INF/lib/ of your application. However, if you have more than 1 application in your Liberty server that need the same libraries, this may not be a good solution.
On to your original question, you can use the maven-dependency-plugin to copy any maven artifact into a particular location during the build. When using this plugin to set up a <library>, be sure to bind the copy step to the prepare-package phase.
Here is an example of adding JUnit to ${server.config.dir}/myLib/ during a Maven build:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/liberty/wlp/usr/servers/myServer/myLib</outputDirectory>
<destFileName>junit.jar</destFileName>
</artifactItem>
</artifactItems>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>

Maven Assembly Plugin jar-with-dependencies -> No Dependencies in Jar

The following reference mentions the descriptor Reference jar-with-dependencies. Afaik it is a predefined assembly, which includes all jar dependencies into a single big self-contained jar file. This is great if you have multiple dependencies and need to copy your project to another machine because you don't need to update/delete obsolete libraries separately.
https://newfivefour.com/category_maven-assembly.html
I added the maven-assembly-plugin to my pom, and the MyTool.jar-with-dependency.jar is created. I expected that the jar contains all external dependencies, but it is the same as the normal MyTool.jar and does not contain any dependencies like apache.commons or apache.logging.
The important detail is that the dependencies scope is set to provided. Without this it works as expected. But I use the scope later on with the maven-dependency-plugin to copy all dependencies in the provided scope to a specific directory.
[...]
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
<scope>privided</scope>
</dependency>
</dependencies>
<build>
<!--pluginManagement-->
<plugins>
<plugin> <!-- This is the plugin I added. -->
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
I use Apache Maven 2.2.1 (rdebian-14).
How can I include the dependencies from the provided scope? Or is there an other solution?

Is it possible to create a WAR and a JAR of same maven project

I have maven project which needs to be exposed as a webservice for 3rd party client but same project needs to be used as a JAR between internal modules.
Is this thing possible using different maven profiles in a single pom.
You can use the configuration in the maven-war-plugin via:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<archiveClasses>true</archiveClasses>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
After you have configured that way you can use the generated jar file as a usual dependency except for the classifier:
<dependency>
<groupId>myGroup</groupId>
<artifactId>myArtifact</artifactId>
<version>myVersion</myVersion>
<classifier>classes</classifier>
</dependency>

How to exclude resource package from being build into jar Maven?

HI i am building an project into a jar file from maven but i want some resource packages not to be included in that jar. Rather i want to build two seperate jars one that contain project and another with those excluded packages. How to do that?
Assuming you are using dependency:copy-dependencies there are two options that will help you:
excludeClassifiers: Comma Separated list of Classifiers to exclude. Empty String indicates don't exclude anything (default).
excludeScope Scope to exclude. An Empty string indicates no scopes (default).
I use this for example to exclude jsp-api.jar from my Struts2 war project. This jar is needed to run StrutsTestCase tests but if it's included in the war, it conflicts with Tomcat lib directori, wich already contains jsp-api.jar
Setting my dependency as this in my pom.xml:
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
And my maven-dependency plugin as this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.basedir}/src/main/webapp/WEB-INF/lib</outputDirectory>
<excludeScope>provided</excludeScope>
</configuration>
</plugin>
I've solved my excluding jar problem when deploying on Tomcat

How to configure a Maven plugin with classpath resource?

Today I configure the Maven war plugin like this :
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>${basedir}/../common/WEB-INF/web.xml</webXml>
</configuration>
This allows me to share that web.xml between several projects.
The problem with this approach is that my Maven project is not self contained. It depends on a relative path on the file system.
Is it somehow possible to do something like this ? :
<webXml>classpath:com/mycompany/common/web.xml</webXml>
And of course, make that file available on the classpath of the plugin.
Thanks
First step is to create a dedicated Maven module with packaging type jar containing the web.xml. Let's call it com.mycompany:common.
Is it somehow possible to do something like this ? :
<webXml>classpath:com/mycompany/common/web.xml</webXml>
Have you tried i.e. you know for sure that it doesn't work? If it did I suppose you'd have to use a leading '/' (/com/...).
And of course, make that file available on the classpath of the
plugin.
That'd be easy then...just add a dependency to com.mycompany:common to make it available in the classpath. Of course it'd have to be available in your Maven repository.
If classpath: doesn't work, I'm really not sure anymore myself, you could use the maven-dependency-plugin to unpack web.xml from the JAR in order to make it available to the maven-war-plugin.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-web-xml</id>
<phase>..any phase before packaging..</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<version>1.0</version>
<outputDirectory>...dir you'll use for the war plugin later...</outputDirectory>
<includes>/com/mycompany/common/web.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Resources