Maven: how to use POM elements from within assembly descriptor - maven

I need to assemble several sets of resources. These sets of resources are related to each other. So, I decided to put them all under the same project and use the assembly plugin to achieve my goal.
I have ended with a POM and a descriptor file for each set of resources.
Let's assume that my project is as follows:
src/main/resources/set1 : contains resources for the first set
src/main/resources/set2 : contains resources for the second set
src/main/resources/set3 : contains resources for the third set
descriptor1.xml : the assembly descriptor for the first set
descriptor2.xml : the assembly descriptor for the second set
descriptor3.xml : the assembly descriptor for the thord set
pom.xml
The content of descriptor1.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>set1</id>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>${project.basedir}/src/main/resources/set1</directory>
</fileSet>
</fileSets>
</assembly>
The content of descriptor2.xml and descriptor3.xml is similar to the content of descriptor1.xml except that set1 (in "/assembly/id" and "/assembly/fieldSets/fieldSet/directory") is replaced by set2 and set3 respectively.
The content of pom.xml is as follows:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>sample.assembler</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<properties>
<maven-assembly-plugin.version>2.4</maven-assembly-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven-assembly-plugin.version}</version>
<executions>
<execution>
<id>set1</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>descriptor1.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>set2</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>descriptor2.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>set3</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>descriptor3.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The above config gives the expected result. However, there are a lot of descriptor files to maintain.
I have read in the documentation that descriptor files are interpolated using project properties, POM element values, user properties, ... before being used.
My question is : is there a way to reference the id of the current execution (some thing like project.build.execution.id)? In such a case, all my three descriptors with be replaced by only one file.
Thank you in advance.

I don't think you can achieve what you want within single run.
But you can create a profiles where earch of the profile will define different properties and you can run your build three times with different profiles to get 3 different file sets.
I do use such approach for generating configuration for different environments. I activate the environment profile and the output is the environment configuration. The configuration is generated by single descriptor which is driven by the profile properties.
EDIT:
Here is a workaround using per-execution propeties which may solve your problem. In the moment I'm not entirely sure if these filters will be used for filtering resources only or you can reference them in the assembly itself for defining lets say <finalName> ...
See: http://olafsblog.sysbsb.de/per-assembly-filtering-with-the-maven-assembly-plugin/

Related

want different maven project structure

Trying to understand maven flow.Need to create a folder called 'my-source' and copy multiple files in the same folder.
And i want a maven build zip file which should contain 'my-source' folder and its contents.How do i do that?Where ever articles i refer am seeing only java project/folder structure examples.
Also i have seen sourcedirectory/outputdirectory. Not sure where i can modify these values as i couldnot find location of effectivepom
So please give me the process to fulfil my requirement
In order to create a zip file with all your contents you will have to use the maven assembly plugin in your pom.xml. Apart from this, you will need one more file (say bin.xml) that will tell which all files you want to be packaged in the zip. The assembly plugin in the pom.xml will simply point to the bin.xml file.
See a sample code for pom.xml below.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.abc</groupId>
<artifactId>xyz</artifactId>
<version>3.1.3</version>
<build>
<plugins>
<plugin> <!-- Create a zip file with the contents you want deployed -->
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<descriptors>
<descriptor>src/assembly/bin.xml</descriptor> // very important. This is where we will tell where our bin.xml is located
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Now create a folder structure like src/assembly and add a file with the name bin.xml. See below for a sample code that should go inside bin.xml.
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>distrib</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/my-source</directory> // the folder that you want to the packaged in the zip file
<outputDirectory>/</outputDirectory> // the location within the zip file where your folder should be copied. In this case it will place the my-source directory at the root level of the zip file.
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>

Don't Generate Windows Sections Using Appassembler

I am only targeting Solaris when using Appassembler and have this in my pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>question</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<id>generate-jsw-scripts</id>
<phase>package</phase>
<goals>
<goal>generate-daemons</goal>
</goals>
</execution>
</executions>
<configuration>
<repositoryLayout>flat</repositoryLayout>
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<target>${project.build.directory}</target>
<configurationDirectory>conf</configurationDirectory>
<daemons>
<daemon>
<id>${project.artifactId}</id>
<mainClass>org.apache.catalina.startup.Bootstrap</mainClass>
<jvmSettings>
<initialMemorySize>512</initialMemorySize>
<maxMemorySize>1024</maxMemorySize>
<extraArguments>
<extraArgument>-Dapp=${project.artifactId}</extraArgument>
<extraArgument>-XX:MaxPermSize=128m</extraArgument>
<extraArgument>-XX:+UseParNewGC</extraArgument>
<extraArgument>-XX:+CMSParallelRemarkEnabled</extraArgument>
<extraArgument>-XX:+UseConcMarkSweepGC</extraArgument>
</extraArguments>
</jvmSettings>
<platforms>
<platform>jsw</platform>
</platforms>
<generatorConfigurations>
<generatorConfiguration>
<generator>jsw</generator>
<includes>
<include>solaris-x86-32</include>
</includes>
<configuration>
<!--Logging-->
<property>
<name>wrapper.logfile.maxsize</name>
<value>10m</value>
</property>
<property>
<name>wrapper.logfile.maxfiles</name>
<value>10</value>
</property>
</configuration>
</generatorConfiguration>
</generatorConfigurations>
</daemon>
</daemons>
</configuration>
</plugin>
</plugins>
</build>
</project>
However, a bat file is still generated and there is a Windows specific section in the generated conf.
Neither are going to stop me running - for instance I can exclude the bat file when using the assembly plugin and I don't think the Windows section will affect me on Solaris.
However, for neatness sake I would rather not generate either in the first place.
Is there a way to prevent them being generated?
EDIT: Added full example pom
EDIT2: I think this is a bug so opened an issue here

How can I override maven property values set by properties-maven-plugin's read-project-properties goal?

In one of our projects, we use the properties-maven-plugin's read-project-properties goal to read property values from a file which are then used for filtering resources. See this post for a discussion on the general purpose of this procedure.
We would like to override some of the values found in the file using a suitable profile defined in the developer specific settings.xml (the same way we override properties set in the POM).
This, however, does not work for the properties set by the properties-maven-plugin.
How can we achieve our goal?
As a work around, we are currently registering an additional, developer specific file with the properties-maven-plugin to achieve this effect but it would be much more convenient to use the regular way (profiles).
In more general terms, the question is: How do properties set by properties-maven-plugin's read-project-properties goal tie into the property definition precedence hierarchy of maven, which is described in this very helpful blog post.
I extracted the relevant elements of our POM into a toy project that demonstrates my issue. Here is the POM of the toy project:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xxx</groupId>
<artifactId>MavenTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Test</name>
<description>A maven project to test filtering and the maven-properties-plugin</description>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<!-- Read properties from a file -->
<execution>
<id>load-filter-properties</id>
<goals>
<goal>read-project-properties</goal>
</goals>
<phase>initialize</phase>
<configuration>
<files>
<file>filters/filterTest.properties</file>
</files>
<quiet>false</quiet>
</configuration>
</execution>
<!-- The following execution is for debug purposes only -->
<execution>
<id>write-project-properties</id>
<inherited>false</inherited>
<goals>
<goal>write-project-properties</goal>
</goals>
<phase>package</phase>
<configuration>
<outputFile>filters/project.properties</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12-beta-1</version>
</dependency>
</dependencies>
</project>
I think you will find the answer here:
Modifications of project properties that happen during project lifecycle have no effect on the effective pom – it is just too late. Examples of such modifications include groovy scripts (via gmaven-plugin) and properties loaded from external files via maven-properties-plugin. So, why do we need them at all? Since they can be used by other plugins in runtime, when they are read directly from properties collection during plugin invocation.
Since the properties are read after the usual resolution they just override whatever was set in profiles.

Using the maven-remote-resources-plugin and specifying the resourcesDirectory

I'm trying to override the default resources directory (src/main/resources) when using the maven-remote-resources-plugin. However the specified value in the sample below doesn't seem to be taken into account. Would appreciate if someone could give me some pointers.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.resource.library</groupId>
<artifactId>resource-library</artifactId>
<version>1.0</version>
<name>ResourceLibrary</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<resourcesDirectory>${basedir}/common</resourcesDirectory>
<includes>
<include>**/*</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
EDIT: I'm wondering if this is a bug in the plugin, since I see the following in the DEBUG output of the build, which implies that its attempting to use the correct resources directory. Nothing else relevant appears in the debug output.
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-remote-resources-plugin:1.5:bundle' with basic configurator -->
[DEBUG] (f) includes = [**/*]
[DEBUG] (f) outputDirectory = C:\jit\workspace\ResourceLibrary\target\classes
[DEBUG] (f) resourcesDirectory = C:\jit\workspace\ResourceLibrary\common
EDIT: I think this may actually be a bug so have raised: MRRESOURCES-96
Why do you need maven-remote-resources-plugin?
If your goal is to override the default resources directory ,then you can use mvn resources:copy-resources, since it's more flexible. An example here.
Alternative
You can also use the resources goal provided by resources plugin, and specify the resources in pom file's block. Example here.
Edit
About maven-remote-resources-plugin, see the usage page:
This will trigger the scanning of that project's $basedir/src/main/resources directory and create the $basedir/target/classes/META-INF/maven/remote-resources.xml manifest file.
That means this plugin will create the remote-resources.xml file, but it doesn't mean that it will copy the resources for you.
I created an empty maven project using your plugin configuration, and it actually did create an remote-resources.xml file. Also, it did not copy the files under ${basedir}/common
To do that, just specify the resources in build section. Example:
<build>
<resources>
<resource>
<directory>${basedir}/common</directory>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<resourcesDirectory>${basedir}/common</resourcesDirectory>
<includes>
<include>**/*</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
kly is right about it not copying resources for you (I apologize, I cannot comment yet - not enough reputation).
With the "bundle" goal, you are only generating a manifest with a list of the included resources. The manifest must be packaged in an artifact along with the resources themselves, which will only happen in your instance if you also use copy-resources to put them in the target/classes directory.
You then must use the "process" goal, and list your bundle, in any other project you wish to use the resources from.

After bumping up version of maven-assembly-plugin from 2.4 to 2.5, files within the assembly are now read-only

I am hoping that someone may be able to explain this change in behaviour of the maven-assembly-plugin w.r.t. file permissions.
This was causing our Eclipse-based application to fail to launch as it was unable to obtain locks on files because of Locking is not possible in the directory C:\eclipse\configuration\org.eclipse.osgi
The original files I am bundling into the built assembly are not read only so I would not expect the files to suddenly become read-only in the zip file. I cannot find any information on changes that might have altered this behaviour; it seems like a regression to me but if it is intentional for whatever reason then users should have been informed about the change in behaviour in the announcement of the release of the 2.5 version of the plugin of in the changelog.
This might be related to the upgrade of the plexus-archiver transitive dependency rather than the upgrade of maven assembly itself.
BTW this is on Windows 7.
Edit: Simple example as requested:
POM configured with a maven-assembly-plugin configured thus,
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<configuration>
<descriptors>
<descriptor>binary.xml</descriptor>
</descriptors>
</configuration>
<id>make-binary</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
referencing an assembly descriptor binary.xml that brings in some arbitrary files, in this case the pom.xml and the binary.xml of the build,
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>binary</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory></directory>
<outputDirectory></outputDirectory>
<includes><include>**</include></includes>
</fileSet>
</fileSets>
</assembly>

Resources