Search

October 6, 2020

Mastering Maven: Replace Files In Archive

In a previous post we learned how to replace a file in an archive with Gradle. In this blog post we use Maven to achieve the same goal. With Maven we first have to extract the contents of the archive and then assemble a new archive where we use a file replacement to replace an original file from the archive. To extract the contents we use the task unzip with the maven-antrun-plugin. To create a new archive we use the maven-assembly-plugin. The destination directory of the extracted contents is the input fileset for the assembly definition together with the files we want to overwrite. The end result is a new archive with replaced files.

In the following pom.xml we configure the maven-antrun-plugin and maven-assembly-plugin:

<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>mrhaki</groupId>
    <artifactId>sample</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <configuration>
                            <target>
                                <!-- We unzip the original archive to target/archive-contents -->
                                <unzip src="lib/sample.zip" dest="target/archive-contents"/>
                            </target>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- Name of new archive -->
                    <finalName>new-sample</finalName>
                    <!-- We don't want the id of the assembly descriptor in the filename -->
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptors>
                        <!-- Descriptor of the contents of the new archive -->
                        <descriptor>src/assembly/sample.xml</descriptor>
                    </descriptors>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The descriptor of the assembly plugin is sample.xml and here we define the contents of the new archive:

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
    <id>sample</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <!-- Files that are extracted from the original archive -->
            <directory>target/archive-contents</directory>
            <outputDirectory/>
        </fileSet>
    </fileSets>
    <files>
        <file>
            <!-- New files that replace files from the original archive -->
            <source>src/main/resources/README</source>
            <outputDirectory/>
        </file>
    </files>
</assembly>

Written with Maven 3.6.3.