Keep permissions on files with Maven resources:testResources - maven

Is it possible to keep permissions on file with Maven resources:testResources? My use case is a Selenium binary driver that I put in /src/test/resources that I would like to be able to use from my tests. My -rwxr-xr-x is however changed to -rw-r--r-- in target/test-classes.

This seems to be a bug in the Maven Resource Plugin
If you are using the Maven Assembly Plugin, you can configure the file permissions there.
If not, you might consider a workaround. You could do this via Ant by doing something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<configuration>
<target>
<chmod file="target/test-classes/test.sh" perm="755"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

I added a profile that gets activated automatically when run on a Unix machine. It executes an in-line shell script to adopt file permissions from all files in a folder recursively to files of the same name in another folder (see SRC and DST variables). The script requires a /bin/sh as well as find, xargs and chmod, which should exist on all modern systems.
<profile>
<id>unix</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>fix-resource-permissions</id>
<goals>
<goal>exec</goal>
</goals>
<phase>process-test-resources</phase>
<configuration>
<executable>/bin/sh</executable>
<arguments>
<argument>-c</argument>
<argument>
set -x
SRC="${basedir}/src/test/resources"
DST="${project.build.directory}/test-classes"
find "$$SRC" -printf "%P\0" | xargs --verbose -0 -I {} chmod --reference="$$SRC/{}" -f "$$DST/{}"
</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

My solution is to execute the scripts in a way that do not mind the flags. So, for instance, when running from Maven Exec Plugin, I use:
Before:
<executable>myScript.sh</executable>
<commandlineArgs>...</commandlineArgs>
After:
<executable>bash</executable>
<commandlineArgs>myScript.sh ...</commandlineArgs>
Note: If you use bash -c, it will also fail if the exec flag is off.
Adding this remarks from Jason van Zyl, one of the creators of Maven:
The maven-resources-plugin was never intended to create any resources that would be used in a naked filesystem. It was strictly intended to place resources into the resultant artifact for use in a platform independent way, in general from the classpath. If you want to move archives around that are going to be unpacked and used I suggest the assembly plugin for making the archives and the dependency plugin for unpacking them.
http://maven.40175.n5.nabble.com/maven-resources-plugin-not-retaining-unix-permissions-td4938002.html

Related

Maven maven-dependency-plugin copy-dependencies ignores outputDirectory

I'm try to use the maven-dependency-plugin's copy-dependencies goal.
I checked its official example with the snippet below.
My problem is: the dependencies are always copied to
target\dependency folder, even if I specify an <outputDirectory> node.
Here is the part of my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
<configuration>
<outputDirectory>${project.build.directory}/aaa</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</executions>
</plugin>
</plugins>
</build>
Question: What I'm doing wrong? Is it possible to declare the output directory outside of the project? For example: c:\temp ?
You configured an execution of the maven-dependency-plugin with a configuration only defined within its scope, hence it will only be picked up by the plugin during a mvn package invocation, that is, while performing the package phase and the plugin (executions) having a binding to it.
If you invoke the plugin from command line as following:
mvn dependency:copy-dependencies
It will indeed only use default values, since your configuration will be ignored.
In fact, the default value for the outputDirectory option is indeed:
Default: ${project.build.directory}/dependency
In maven, a plugin configuration can be defined as general configuration (outside of an execution section, applied to all executions and to command line invocations) or per execution (within an execution section, like in your case).
In your case, you probably want the configuration to be valid in both cases, so simply change your plugin section to the following:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<configuration>
<outputDirectory>${project.build.directory}/aaa</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note: we moved up the configuration, from execution scope to plugin (global) scope.
Also note, in the configuration above we kept the execution, which means maven will always execute this plugin goal at each an every mvn package invocation. If you don't want this behavior and only expect to use the command line execution, then you can remove the executions section at all.
Since Maven 3.3.1 it's also possible (see the note at the very end of Using the executions Tag section):
Since Maven 3.3.1 this is not the case anymore as you can specify on the command line the execution id for direct plugin goal invocation.
to execute copy-dependencies execution directly not modifying your pom at all:
mvn dependency:copy-dependencies#copy-dependencies
Note that of the two copy-dependencies separated by #, the former refers to the plugin goal and the latter refers to the execution id. And general direct invocation of an execution is:
mvn <plugin-prefix>:<goal>#<execution>
See also accepted answer to almost the same question

IOException thrown when processing xsd dependencies in maven

I have a problem while processing .xsd file during my maven build.
I use jaxb2 plugin but I have to download external dependiencies from my .xsd files. The problem is that these dependencies (.xsd) are from enviroment which is unstable and very often my build fails because maven cannot download xsd file. How to configure jaxb plugin to force him to try download xsd few times to prevent build failure?
Part of my pom.xml configuration:
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<configuration>
<strict>false</strict>
<extension>true</extension>
<args>
<arg>-Xfluent-api</arg>
<arg>-XtoString</arg>
<arg>-Xsetters</arg>
<arg>-XenumValue</arg>
</args>
<plugins>
<plugin>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>${jaxb.fluentapi.version}</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.9.3</version>
</plugin>
</plugins>
<bindingDirectory>src/main/resources/jaxb</bindingDirectory>
<bindingIncludes>
<include>bindings.xml</include>
</bindingIncludes>
<schemas>
<schema>
<fileset>
<!-- Defaults to schemaDirectory. -->
<directory>${project.basedir}/src/main/resources/orbeons</directory>
<!-- Defaults to schemaIncludes. -->
<includes>
<include>*.xsd</include>
</includes>
</fileset>
</schema>
</schemas>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/generated-sources/orbeons</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Author of the maven-jaxb2-plugin here.
You have two parts here: managing the downloads of external resources and compiling the schemas, rewriting "external" links to local files.
The first (managing downloads) is not in the scope of the maven-jaxb2-plugin, the second is supported with
catalogs.
In short, you can create a catalog file like this:
REWRITE_SYSTEM "http://www.w3.org" "w3c"
Or this:
REWRITE_SYSTEM "http://schemas.opengis.net" "maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc"
And use this file to "rewrite" absolute links to local files or resources within Maven artifacts:
<configuration>
<catalog>src/main/resources/catalog.cat</catalog>
</configuration>
As for the first part, I don't think managing downloads with retries, continuations and all other stuff should be in the scope of the JAXB2 Maven plugin.
ps. You don't need build-helper-maven-plugin/add-source with maven-jaxb2-plugin, source directory is added automatically.
Apparently the maven-jaxb2-plugin does not support such a feature. (And neither does the maven-download-plugin nor even the maven-dependency-plugin).
Three solutions come into my mind at the moment (plus two and a half inspired by LIttle Ancient Forest Kami's comment) [Numbers reflect the precedence of what I would do]:
Use a CI tool (Jenkins, etc.) that supports retry on job failure. [1]
Handmade:
Use the GMavenPlus plugin with a script ... [2]
Use the Maven AntRun plugin with a script ... [3]
Use the Exec Maven plugin with a program ... [5]
... that performs the download and retry and bind it to the generate-resources phase in your project's POM.
Create a Maven plugin with appropriate parameters (url, outputDirectory, retryCount) that uses the maven-download-plugin and performs the retry. Bind its goal to the generate-resources phase in your project's POM. [4]
Create a check-download Maven project that uses the maven-download-plugin bound to the generate-resources phase to download the .xsd. [6]
Create a shell script that contains the following (in pseudo code):
download:
counter++
<check-download project>/mvn generate-resources
if error and counter < maxRetryCount goto download
if not error
<your project>/mvn ...
else
display appropriate error message
There is also a question Maven download retry? from 2005. Unanswered.

Create Symlink for dependencies in Maven assembly

I have a Maven assembly that after unpacking the tar, creates three directories
each containing a /lib directory. So e.g.
folder1/lib
folder2/lib
folder3/lib
Currently, I am packing a same .jar in each of these /lib directories. Since this is a waste of space, I was wondering if I could have just one copy of that .jar and create something like a symlink for other two locations that could reference that .jar?
Thanks!
Here is my solution with maven-antrun-plugin for very similar situation. Zookeeper dependencies are previously placed into ${basedir}/target/package/lib by maven-dependency-plugin. Now I'm creating symlinks for all libraries into ${basedir}/target/package/lib/zookeeper/lib which point 2 dirs upper.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>prepare-delivery</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<!-- Prepare zookeeper layout. -->
<mkdir dir="${basedir}/target/package/lib/zookeeper/lib"/>
<apply executable="ln" dir="${basedir}/target/package/lib/zookeeper/lib" relative="true">
<arg value="-s"/>
<srcfile prefix="../../"/>
<targetfile/>
<fileset dir="${basedir}/target/package/lib" includes="**"/>
<mapper type="identity"/>
</apply>
</target>
</configuration>
</execution>
</executions>
</plugin>
Plugin management for antrun is set as following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
</plugin>
I believe this is unsupported in Maven packaging and assembly. Another Stack Overflow question from just a year ago asked the same thing and got the "unsupported" answer. And there have been two JIRAs on this feature (at least) that have been open for quite some time: one for the assembly plugin and one for Plexus components. I would say this the odds of this ever being directly supported are not good.
Just FYI, if I say "source project," I'll be refering to the project that assembled the tar. If I say "destination project," I'll mean the one unpacking the tar. This is assuming you have Maven projects on both sides- if that assumption is wrong, you should rely on command line utilities to do the tar-ing or untar-ing for you.
Since it sounds to me like you are unpacking the tar in the context of a Maven build, there are ways of working around this. As far as I know, the best solution if symlinking is important to you is to use either the junction plugin, the exec-maven-plugin, or the maven-antrun-plugin.
The junction plugin has the advantage of being portable, even on Windows. The problem is the project doing the unpacking must have explicit knowledge of the structure of the original structure of the tar, which is generally not desirable as it will now have to be updated should the intended symlinking that is changed. The plugin also seems to be pretty unmaintained, so there's that.
The exec plugin will allow you to call commandline utilities or scripts to do your linking, but you will have to toy with profiles to get crossplatform capabilities. The best benefit of doing it this way is that the project doing the unpacking is completely agnostic of the original structure of the tar. The details of the mechanism are in the question from a year ago that I mentioned above.
For my project, I am probably going to use antrun for Ant's symlink task- it is possible to have Ant record all symlinks to a file on the source side, and then package that file along with Maven. The receiving project can then check for the file and recreate its symlinks. This allows the symlinking intended for the tar distribution to be changed from its source project with no changes on the destination project. My project only supports OS X and Linux, so this is acceptable- you will need to decide which is best for you.
In either case, you will unfortunately have a situation where the project doing the unpacking must have knowledge about the way the tar was before being packed.
You can use symlink task/goal of ant-run plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<symlink link="folder2/lib/${project.artifactId}-${project.version}.jar"
resource="folder1/lib/${project.artifactId}-${project.version}.jar"/>
<symlink link="folder3/lib/${project.artifactId}-${project.version}.jar"
resource="folder1/lib/${project.artifactId}-${project.version}.jar"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
If you want the symlinks to have relative path, you can give relative path in resource like below
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<symlink link="folder2/lib/${project.artifactId}-${project.version}.jar"
resource="../../folder1/lib/${project.artifactId}-${project.version}.jar"/>
<symlink link="folder3/lib/${project.artifactId}-${project.version}.jar"
resource="../../folder1/lib/${project.artifactId}-${project.version}.jar"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

Specify javaagent argument with Maven exec plugin

I have a similar question to: this previous question
I am converting a Java project using Netbeans to Maven. In order to launch the program, one of the command-line arguments we need is the -javaagent setting. e.g.
-javaagent:lib/eclipselink.jar
I'm trying to get Netbeans to launch the application for development use (we will write custom launch scripts for final deployment)
Since I'm using Maven to manage the Eclipselink dependencies, I may not know the exact filename of the Eclipselink jar file. It may be something like eclipselink-2.1.1.jar based on the version I have configured in the pom.xml file.
How do I configure the exec-maven-plugin to pass the exact eclipselink filename to the command line argument?
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<executable>java</executable>
<arguments>
<argument>-Xmx1000m</argument>
<argument>-javaagent:lib/eclipselink.jar</argument> <==== HELP?
<argument>-classpath</argument>
<classpath/>
<argument>my.App</argument>
</arguments>
</configuration>
</plugin>
I figured out a way that seems to work well.
First, setup the maven-dependency-plugin to always run the "properties" goal.
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>getClasspathFilenames</id>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
Later on, use the property it sets as documented here with the form:
groupId:artifactId:type:[classifier]
e.g.
<argument>-javaagent:${mygroup:eclipselink:jar}</argument>
Simply define a property for the eclipse link version and use the property in your <dependency> and the exec plugin:
<properties>
<eclipselink.version>2.4.0</eclipselink.version>
</properties>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>${eclipselink.version}</version>
</dependency>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<executable>java</executable>
<arguments>
<argument>-Xmx1000m</argument>
<argument>-javaagent:lib/eclipselink-${eclipselink.version}.jar</argument>
<argument>-classpath</argument>
<classpath/>
<argument>my.App</argument>
</arguments>
</configuration>
</plugin>
the maven-dependency-plugin and exec-maven-plugin should be put under the node ,otherwise it will not work

How to include external source files in maven-jar-plugin

We are building a jar file from external(to the project) classes.
That works fine but we have not been able to figure out how to also include the external source files. I have tried using the "< includes >" tag but only end up with a manifest file in the final jar when used. I have looked at using the maven-resources-plugin but either I used it wrong or it doesn't work in my case. Here is a copy of our of code:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<!-- <phase>generate-resources</phase> -->
<phase>clean</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesDirectory>${itendant.path}/web/rocket/WEB-INF/classes</classesDirectory>
<finalName>${itendant.jar.name}</finalName>
<outputDirectory>${itendant.jar.path}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Sources? Do you mean external dependencies? These should also be managed with maven, using mvn deploy:deploy-file as described on http://maven.apache.org/plugins/maven-deploy-plugin/usage.html , and imported in your pom.xml.
If you really mean external resources, then a proper resources declaration would be:
<project>
...
<build>
...
<resources>
<resource>
<directory> [your folder here] </directory>
</resource>
</resources>
...
</build>
...
</project>
You can have multiple tags if you have multiple resource directories, of course. Also note that building anything during clean is questionable, as clean is not run every build - package would be a better option.

Resources