Maven test jar including dependencies - maven

My project is divided into several modules, one of them is common which is supposed to be used to other modules.
In this module there are TestUtils which I want to be able to use from other modules.
My libraries does not seem to be added to the test-jar. How can I achieve this?
+ common
++ lib
++ src
+++ test
++++ java
++++ resources
+ pom.xml
My pom.xml contains some libraries which I include via system path, such as:
<dependency>
<groupId>com.ibm</groupId>
<artifactId>com.ibm.disthub2.dhbcore</artifactId>
<version>5.3.07</version>
<scope>system</scope>
<systemPath>${basedir}/lib/dhbcore.jar</systemPath>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

Simple answer: Not possible. The test-jar is only intended for compiled classes under the folder src/test/java inclusive src/test/resources but not for supplemental jar files.
Apart from that using a system scope is in general a bad idea.
Best is to put such jars into the company nexus and use it as a usual dependency. A lib folder in a Maven project is generally in indicator of build smells and should be avoided.
BTW: Why are you using such old versions of maven-jar-plugin (2008 version 2.2). Current version version 2.5 from this year.

Related

Maven - How to extract a dependency inside another ZIP dependency?

I have a maven project.
Inside that project, I have a .zip dependency that carries a jar and I need to extract that jar out of the zip dependency and have maven use the jar as a dependency. I can currently download and unpack the zip but, cannot figure out a way to add the unpacked jar as a dependency for the project during the build process.
Here is what I'm currently doing for unpacking:
<dependency>
<groupId>com.bar</groupId>
<artifactId>foo</artifactId>
<version>${foo.version}</version>
<type>zip</type>
</dependency>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>validate</phase>
<configuration>
<includeGroupIds>com.bar</includeGroupIds>
<includeArtifactIds>foo</includeArtifactIds>
<outputDirectory>${basedir}/target</outputDirectory>
<type>jar</type>
</configuration>
</execution>
</executions>
</plugin>
I read up on some other posts that you could try adding the jar to the class path using this.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
Even doing so I was still unable to reference the packages in foo.jar in my project.
Can someone help me?
For maven to use it without subtly breaking stuff elsewhere, you must install the jar into your local repository.
I would suppose that a combination of unpacking the zip file in target/ and then invoking install:install-file on the resulting jar could do what you need. I asked some years back how to integrate that in a normal build - you might find the answer relevant. Multiple install:install-file in a single pom.xml
Let's assume that, after unpacking the zip, you have foo.jar in your module's target folder: ${project.build.directory}/foo.jar
Having this in place, you can then declare a System Dependency pointing to that jar, e.g.
<dependency>
<groupId>foo</groupId>
<artifactId>foo.jar</artifactId>
<systemPath>${project.build.directory}/foo.jar</systemPath>
</dependency>
Tip: if you dont want to delete/re-download the jar each time you do a clean (some IDE will complain the the jar is not always present) just download it once in the ${project.basedir}.
To download the jar once, you can put your "unpack" execution in a profile that gets activated only when the jar is missing.
<profiles>
<profile>
<activation>
<file>
<missing>${project.basedir}/foo.jar</missing>
</file>
</activation>
...
</profile>
</profiles>
Some time ago, I've faced the same problem. I had a zip file as my dependency, and during the build process I need to extract it and separate the content inside my generated package.
I don't know what are you using to deliver your project, but at that time I've used the maven-antrun-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>2.6</version>
</plugin>
With this, I've used the tag unzip inside my target configuration. As you can see here or here. I just don't recommend you to use the task tag as they're using, you'd better prefer the target tag.
Hope it helps you.

Does the Maven Versions Plugin read rules also from classpath?

The Maven Versions Plugin supports the defintion of rules to customize the version resolution process for goals as versions:display-plugin-updates or versions:display-dependency-updates. The location of the rules file can be specified by the rulesUri and the functionality behind this is provided by Maven Wagon.
Therefore I would like to know if it is also supported to provide a rule set within a Jar? I would like to one rule set for multiple projects.
A patch by me has been released with version 2.5 of the Versions Maven Plugin
Now it is possible to create a version rules file and to place it on the classpath.
This example below shows how to reference a rules file called rules.xml
which is provided in a jar on the classpath:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<rulesUri>classpath:///rules.xml</rulesUri>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>your.organisation</groupId>
<artifactId>rulesspec</artifactId>
<version>1234</version>
</dependency>
</dependencies>
</plugin>
Please keep in mind that the provided URI must start with classpath://.

Can I have maven artifact run maven plugin when it is installed?

I have created a Maven plugin (called unpackTemplates) that unpacks a dependency jar file and copies resource files (in this case, templates) from it into a specific location in a project.
Right now, I put the following into the pom file of every project that has a dependency with templates. It looks like:
<project>
<groupId>DuriansAreDope</groupId>
<artifactId>DuriansAreDope</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugin>
<groupId>mycorp</groupId>
<artifactId>unpackTemplates</artifactId>
<version>1.0</version>
<executions>
<execution>
<configuration>
<groupId>com.mycorp.lib</groupId>
<version>1.0</version>
<artifactId>Lib-With-Templates</artifactId>
</configuration>
<goals>
<goal>unpackTemplates</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<pluginManagement>....</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.mycorp.lib</groupId>
<artifactId>Lib-With-Templates</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
The above project pom works for us. It calls the plugin and the plugin does it's job. However, we'd like to avoid adding the plugin section to the pom of every project.
It would make more sense to put that plugin section in the dependencies pom. This way the project pom does not need to be modified beyond adding the <dependency> tags as usual. And the dependency has it's plugin run wherever it is installed.
I've seen that the pom file for Gson contains a <build><plugins>...</plugins></build> section in it. When I give my dependencies the following pom files, however, the plugin is not run (although the dependency is found, downloaded, installed, etc correctly).
<project>
<groupId>com.mycorp.lib</groupId>
<artifactId>Lib-With-Templates</artifactId>
<version>1.0</version>
<build>
<plugin>
<groupId>mycorp</groupId>
<artifactId>unpackTemplates</artifactId>
<version>1.0</version>
<executions>
<execution>
<configuration>
<groupId>com.mycorp.lib</groupId>
<version>1.0</version>
<artifactId>Lib-With-Templates</artifactId>
</configuration>
<goals>
<goal>unpackTemplates</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<pluginManagement>....</pluginManagement>
</build>
</project>
Any ideas what I'm doing wrong, or if the Gson pom is simply doing something else entirely?
(NB: The groupId/version/artifactIds in <configuration> are necessary because they are (string) parameters to the plugin; presumably if I got the run-straight-from-dependency approach working I could refactor them away, but again, it's not even running the kludgy version with parameters.)
two points:
First I agree with khmarbaise in that you don't need a plugin of your own for those tasks. To unpack to a specific location you can use dependency:unpack-dependencies and outputDirectory parameter.
If you need more configuration you can use the assembly plugin to structure your artifact (which you want to unpack).
For the second point it seems to me that you want to use the contents of your lib-with-templates in many projects. Why don't you add the plugin and dependency to a parent pom which you include in every pom where you need it? Then you don't need to declare it in "every pom". If you don't really need it in every pom you can put it in a profile and choose a proper activation for it.
HTH!

How to include resources from war to another maven project

I have a maven project , which needs to copy webapp/WEB-INF/ resources from another maven project which is packaged as a war .
How do I do it ?
PLease suggest
As Bittrance said, you should use the maven dependency plugin.
The better way is to create project that include all your shared resources, probably a type zip, which is build up with the assembly plugin. This is the good "maven way". It's a better solution than unpacking a war.
Then, refer it
<dependency>
<groupId>com.mygroup/groupId>
<artifactId>my-dependencies</artifactId>
<version>1.0.0</version>
<type>zip</type>
</dependency>
Next, you use the maven dependency plugin to unpack your resources, in the directory of your choice (probably WEB-INF/ ?)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-cfg-test-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/WEB-INF/</outputDirectory>
<includeArtifacIds>my-resources</includeArtifacIds>
<excludeTypes>pom</excludeTypes>
<excludeTransitive>true</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
I'm not realy sure of this code snippet (written for another purpose), but this is an example.
For more information, please follow this link : http://maven.apache.org/plugins/maven-dependency-plugin/
If you can't shared a common-project including your files, you can unpack war including only ftl (or whatever you want), but it's not a realy clean solution ;)
There is a lot of posts that deal with this subject :
Unzip dependency in maven
...
Just try with the keywords maven-dependency-plugin, unpack :)
Hope that will help you.
I can see some alternatives:
Use external references in your version control system to point all repos to the same files.
The Maven Dependency module can copy and unpack project dependencies. From there, you can use the Maven Assembly plugin (or Ant targets) to include parts of that dependency in your own installation.
At least for the FTL files, perhaps you could package them in a separate Jar file and then load them as resources through the class loader.
If the resources are filtered, you may get into problem with solution 1 if you want the filtered version and 2, 3 if you want the source version.
Hope this helps.
(This assumes your dependent project is java (jar) and not another web app, if it is a webapp I think the solution is similar).
I suggest a (slightly) different approach:
Instead of reading resources from war, add this to your war pom, to generate a jar in the artifact as well as a war:
<!-- maven war plugin config -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<configuration>
...
<attachClasses>true</attachClasses>
<classesClassifier>some-string</classesClassifier>
</configuration>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
</plugin>
...
<resources>
<!-- This is for inclusion in the jar, so dependent module can load it -->
<resource>
<targetPath>some-path</targetPath>
<directory>src/main/webapp/path...</directory>
<includes>
<include>your-resource</include>
</includes>
</resource>
</resources>
And this to your consuming pom, so the generated jar will be loaded:
<dependency>
<groupId>com.company</groupId>
<artifactId>...</artifactId>
<classifier>some-string</classifier>
</dependency>
Then you will be able to load the resources the usual way (getResourceAsStream("some-path/your-resource"))

maven-bundle-plugin problem (OSGI)

I have a project with produces an OSGI bundle using the maven-bundle-plugin. The configuration looks like this:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.1.0</version>
<extensions>true</extensions>
<inherited>true</inherited>
<configuration>
<instructions>
<Export-Package>${bubble.osgi.exports}</Export-Package>
<Import-Package>${bubble.osgi.imports}</Import-Package>
<Embed-Dependency>${bubble.osgi.embed.dependencies}</Embed-Dependency>
<_versionpolicy>[$(version;==;$(#)),$(version;+;$(#)))</_versionpolicy>
</instructions>
<versions>
<bubble.osgi.version.clean>${project.version}</bubble.osgi.version.clean>
</versions>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>cleanVersions</goal>
</goals>
</execution>
</executions>
</plugin>
The outcome of the project is a single jar file with all the osgi stuff, embedded dependencies etc. included. I rather would like to have 2 jars as outcome, one with the osgi stuff included and one without, as the embedded dependencies cause problems when using it just as a plain jar.
Is there any other way than using the maven assembly plugin for this?
You can move maven-bundle-plugin configuration into separate profile and use something like
mvn package -Posgi
or default. But there will only one artifact produced per build.
I would recommend to use 2 different pom.xml files (in the project) which will produces 2 different artifacts.
The default pom.xml should generate the plain library like foo:bar:1.0.0
Another pom-osgi.xml should generate the OSGi library like foor:bar-osgi:1.0.0
To build the library with another pom use
mvn -f pom-osgi.xml install

Resources