How do I include third party libraries in openLiberty maven build - maven

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>

Related

Create the configuration file at maven install and without or before feature install for Karaf

In my project, in the bundle module, at resource directory, I have my sample startup.cfg file. This file contains properties I want to use at the startup. In the bundle pom.xml I have the following.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/classes/startup.cfg</file>
<type>cfg</type>
<classifier>config</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
And in my feature xml, I have,
<feature name="my-sample-feature" description="Sample service" version='${project.version}'>
<bundle>mvn:org.sample.app/service.implementation/{{VERSION}}</bundle>
<configfile finalname="/etc/org.sample.app.startup.cfg">mvn:mvn:org.sample.app/service.implementation/{{VERSION}}/cfg/config</configfile>
</feature>
In feature xml, I have added,
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>service.implementation</artifactId>
<version>${project.version}</version>
<classifier>config</classifier>
<type>cfg</type>
</dependency>
This feature is a startup feature too. Now, when I install the feature in a karaf container or in this case when I spin up the karaf, only then the etc/org.sample.app.startup.cfg is created. My target is simple, to have this conf file always at etc/ independent of the feature is installed or not.
The cfg file are deployed into etc folder when installing the feature . If you want it to be present independent of the feature is installed or not, this means that you have to deploy it manually to etc and this is more simple after attaching the cfg to your artifact as you did in your pom.
Remember that if you want to follow best pratices (especially in a production environnement), don't separate cfg deployment from it's origin feature.

Including third party AMP in main project in Alfresco Maven SDK, especially WCMQS

This is the scenario, I have a group of a AMPs, some developed by myself, and other developed by other developer/vendors.
If I am not wrong, using the Maven SDK I can develop and run only one specific AMP at a time.
What steps can be taken to have an external AMP being deployed along with the main project AMP at start up which is when running mvn integration-test -Pamp-to-war.
In particular I am interested in having Alfresco load the wcmqs module.
Assuming you already have the external amps available to maven (either because their're on Maven Central repo or because they're installed locally), you simply add the external amps as dependencies in your amp project. E.g.:
<dependency>
<groupId>org.sharextras</groupId>
<artifactId>javascript-console-repo</artifactId>
<version>0.6.0</version>
<type>amp</type>
</dependency>
You also must configure the maven dependency plugin. You can do it in a profile so it can be turned on or off depending on your needs:
<profiles>
<profile>
<id>unpack-deps</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-amps</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeTypes>amp</includeTypes>
<outputDirectory>${alfresco.client.war.folder}</outputDirectory>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>maven-amp-plugin</artifactId>
<version>3.0.2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
</profiles>
This way, you can start the main project amp plus its dependencies with the following command:
mvn integration-test -Pamp-to-war -Punpack-deps
For a complete pom.xml example see: https://github.com/douglascrp/alfresco-value-assistance/blob/master/alfresco-value-assistance-repo/pom.xml

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>

Unpack an EAR file using maven

I have an EAR file from some build. I want to extract the contents of this EAR file into another folder. I am confused how to do this. I have looked and tried
http://maven.apache.org/plugins/maven-ear-plugin/
and
http://maven.apache.org/plugins/maven-dependency-plugin/usage.html
but either maven is unable to find the file or it has dependency issues.
Since I am new to maven I don not understand how to set these plugins up.
I got the following error on using the below plugin.
Failure to find ECM:ECM:ear:1.0 in http://repo.maven.apache.org/maven2 was cached in the local repository
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>ECM</groupId>
<artifactId>ECM</artifactId>
<version>1.0</version>
<type>ear</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
You can do it using dependency:unpack-dependencies. I just modify my answer because according to your comments, your ear is generated by some other build. If you do not have an Enterprise repository that you can deploy your ear artifact, you have to use "system" scope, but please note that it is usually discouraged.
Add below dependency to your pom.xml
<dependency>
<groupId>ECM</groupId>
<artifactId>ECM</artifactId>
<version>1.0</version>
<type>ear</type>
<scope>system</scope>
<systemPath>/path/to/your/abc.ear</systemPath>
</dependency>
Add the below plugin to your postBuild module pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>ECM</includeArtifactIds>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Have you looked at this example of Maven EAR plugin for Unpacking a module yet?
The Maven Dependency Plugin and its unpack goal can do this.
Sample configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>myear</groupId>
<artifactId>myear</artifactId>
<version>1.0</version>
<type>ear</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
This takes the 'myear.ear' artifact and extracts it to the 'target/earoutput' directory. This also works with JARs, WARs and any other zip-like file. The phase this executes under is 'package' - this may be too late if you need to use these resources in other parts of the build. Change the phase to something earlier such as 'generate-resources' if needed.
You mentioned that you already tried using the dependency plugin. Is the EAR file from another Maven project, and has it been installed in the local Maven repository? If it still doesn't work post the plugin configuration you tried to use.
(edit: update information on dependencies and local repository)
For this to work, your EAR file needs to be put into your local Maven repository (this is just a directory on your disk). But if other people need to build your project as well, you have a few options:
import the EAR into your local repository, and also deploy to a remote repository so everyone can get it (recommended, but requires you to set up a corporate Maven repository)
give the EAR to everyone and have them put it into their local repository using a couple of Maven commands (might be OK for a few developers, less overhead than setting up a whole repository server)
check the dependent EAR into source control under your project and unpack it (not the recommended way of doing things) in a goal in your project
Importing into your local repository is easy. It's very similar to these instructions.
Use the following command:
mvn install:install-file -Dfile=<path-to-EAR-file-on-local-filesystem> -DgroupId=myear
-DartifactId=myear -Dversion=1.0 -Dpackaging=ear
(modify path, groupId, artifactId and version as needed)
Group ID and artifact ID are there simply to uniquely identify artifacts.
Once you install this in the local repository, the dependency plugin should work and find the artifact.

XML maven artifact not on classpath

I have some external configuration (XML files) that are installed in Maven. I need to have them on my test classpath but they aren't appearing.
They must stay as XML, I cannot package them inside a Jar - but I am willing to try anything else for this, custom plugin etc.
(Please don't inform me that Maven is only for Jars - that's simply not true (and if you provide a reference refuting that I can assure you it's out-of-date/misinformation).
The dependencies are specified thus:
<dependency>
<groupId>some.group</groupId>
<artifactId>some.artifact</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>xml</type>
<classifier>some.classifier</classifier>
</dependency>
These XML artifacts have been created by the build-helper plugin (so there's no 1-2-1 with their project's POM).
My only current hacky solution is to, check for the M2_HOME property and load the files from there (as they're defined as dependencies Maven does pull them down) - but I'm not happy with this.
EDIT: The next best hack is probably to use the maven-dependency-plugin to copy these to the output directory (target/classes). If my config is fine for Jars then this smells like a Maven bug.
EDIT 2: #khmarbaise asked for the build-helper-plugin config:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>target/classes/ddl-seed.xml</file>
<type>xml</type>
<classifier>ddl-seed</classifier>
</artifact>
<!-- ... more definitions -->
This generates the correct maven-metadata-local.xml data for all the XML artifacts.
Unfortunately I can find no way of forcing maven to add the test dependency specified to the test classpath, other than this stinky hack of copying it to a directory on the test classpath.
This seems the quickest way (it's for a test dependency), avoiding any JAR creation.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-test-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.acme.gid</groupId>
<artifactId>com.acme.aid</artifactId>
<version>${project.version}</version>
<classifier>ddl</classifier>
<type>xml</type>
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Resources