Using maven to build multiple resources assemblies that are very similar
Solution 1
Assuming the following structure:
src/
└── main
├── assembly
│ └── iterator.xml
└── environment
├── dev
│ └── server.properties
├── pretest
│ └── server.properties
├── production
│ └── server.properties
├── qa
│ └── server.properties
└── test
└── server.properties
where you can use the following assembly-descriptor like this:
<assembly>
<id>${item}</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<outputDirectory>WEB-INF</outputDirectory>
<directory>${basedir}/src/main/environment/${item}/</directory>
<includes>
<include>**</include>
</includes>
</fileSet>
<fileSet>
<outputDirectory>WEB-INF</outputDirectory>
<directory>${project.build.directory}/environment/${item}</directory>
<includes>
<include>**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
using the iterator-maven-plugin will solve the problem:
<build>
<plugins>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>iterator-maven-plugin</artifactId>
<version>0.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>executor</goal>
</goals>
<configuration>
<items>
<item>dev</item>
<item>test</item>
<item>qa</item>
<item>production</item>
<item>pretest</item>
</items>
<pluginExecutors>
<pluginExecutor>
<goal>single</goal>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/iterator.xml</descriptor>
</descriptors>
</configuration>
</pluginExecutor>
</pluginExecutors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The iterator-maven-plugin is available via maven central. I think you can adapt the above configuration/structure to your problem.
Solution 2
Having messed with a similar problem for a long time, I got rid of tons of XML code, using the following workarounds:
Create the same zip archive for all the environments; resources should be extracted or accessed depending on environment (server's hostname, environment variables, etc.)
Create a single JAVA/Groovy class that will build all the necessary environment-specific assemblies and run it through maven-exec-plugin execution.
Comments
-
FrustratedWithFormsDesigner almost 2 years
I'm having a problem with this very redundant maven configuration.
The application I'm working on sometimes gets built for environments that need alternate resource bundles. The current way the resources are prepared for deployment is that they are added to a single .zip file. The build master then deploys the zipped resources to the server. For some environments, alternate versions of some of the resources need to be used. The folder structure in the project looks like this:
src/main/resources - resource1 - resource2 - resource2 ENV1/ -resource1 (environment-specific) ENV2/ -resource1 (environment-specific) -resource3 (environment-specific)
For most environments, the resource zip file needs to contain the files
resource1
,resource2
,resource3
. ForENV1
, the zip file needs to containENV1/resource1
,resource2
,resource3
. ForENV3
, the zip file needsENV2/resource1
,resource2
,ENV2/resource3
.I am currently doing this with an assembly descriptor for each environment, and a separate execution in my POM file:
<plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.4</version> <executions> <execution> <id>zip-normal-resources</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <descriptor>assembly-descriptor.xml</descriptor> </configuration> </execution> <execution> <id>zip-ENV1-resources</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <descriptor>assembly-descriptor-ENV1.xml</descriptor> </configuration> </execution>
And each descriptor looks very similar. The "normal" assembly desrciptor:
<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>Resources</id> <includeBaseDirectory>false</includeBaseDirectory> <formats> <format>zip</format> </formats> <fileSets> <fileSet> <directory>src/main/resources</directory> <includes> <include>*.properties</include> <include>*.xml</include> </includes> <outputDirectory>/</outputDirectory> <filtered>true</filtered> </fileSet> <fileSet> <directory>${project.build.outputDirectory}/resources</directory> <outputDirectory>/</outputDirectory> <includes> <include>**/*</include> </includes> </fileSet> </fileSets> </assembly>
An environment-specific descriptor:
<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>Resources-ENV1</id> <includeBaseDirectory>false</includeBaseDirectory> <formats> <format>zip</format> </formats> <fileSets> <fileSet> <directory>src/main/resources</directory> <includes> <include>*.properties</include> <include>*.xml</include> </includes> <!-- exclude environment-specific files --> <excludes> <exclude>resource1</exclude> </excludes> <outputDirectory>/</outputDirectory> <filtered>true</filtered> </fileSet> <fileSet> <directory>src/main/resources/ENV1</directory> <includes> <include>*.properties</include> <include>*.xml</include> </includes> <outputDirectory>/</outputDirectory> <filtered>true</filtered> </fileSet> <fileSet> <directory>${project.build.outputDirectory}/resources</directory> <outputDirectory>/</outputDirectory> <includes> <include>**/*</include> </includes> </fileSet> </fileSets> </assembly>
This solution works but it feels very inefficient. I don't like having multiple assemblies for each environment that are almost identical, except for the environment names. Is there any way to streamline this?
-
FrustratedWithFormsDesigner over 10 yearsThis was really a two-part question: refactoring out the common stuff in the assembly descriptors can be done with component descriptors: maven.apache.org/plugins/maven-assembly-plugin/examples/single/… also here: maven.apache.org/plugins/maven-assembly-plugin/component.html
-
Denis Kulagin about 10 yearsGroovy was the only reasonable solution in my case too.
-
khmarbaise about 8 yearsThis might be a simpler alternative in the meantime: github.com/khmarbaise/multienv-maven-plugin