如何配置maven-assembly-plugin调整tar.xz包内文件顺序以优化压缩率
Great question! The maven-assembly-plugin doesn't have built-in support for reordering files in the generated archive to group identical content together for better xz compression. But we can work around this by splitting the process into two steps: first generate an uncompressed tar archive, then reorder its contents by file content (to group duplicates) and recompress it into txz. Here's how to implement this:
Step 1: Adjust the Maven Assembly Plugin to Output an Uncompressed Tar
First, modify your pom.xml to have the assembly plugin generate a raw tar file instead of txz—we'll handle compression later after reordering:
<build> <plugins> <!-- Modified assembly plugin: output tar instead of txz --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <finalName>myapp</finalName> <descriptors> <descriptor>delivery/assembly/distribute-install.xml</descriptor> </descriptors> <!-- Switch format from txz to tar --> <formats> <format>tar</format> </formats> </configuration> </execution> </executions> </plugin> <!-- Add plugin to copy and set permissions on our reorder script --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <executions> <execution> <id>copy-scripts</id> <phase>prepare-package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.directory}</outputDirectory> <resources> <resource> <directory>src/main/scripts</directory> <includes> <include>reorder-tar.sh</include> </includes> <fileMode>0755</fileMode> <!-- Make script executable --> </resource> </resources> </configuration> </execution> </executions> </plugin> <!-- Add exec plugin to run the reordering script --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>${project.build.directory}/reorder-tar.sh</argument> <argument>${project.build.directory}/myapp.tar</argument> <argument>${project.build.directory}/myapp.txz</argument> </arguments> </configuration> </execution> </executions> </plugin> </plugins> </build>
Step 2: Create the Reordering Script
Create a shell script src/main/scripts/reorder-tar.sh that will:
- Extract the raw tar to a temporary directory
- Sort files by their content hash (to group identical files together)
- Recreate the tar with sorted files and compress it to txz
#!/bin/bash INPUT_TAR="$1" OUTPUT_TXZ="$2" TMP_DIR=$(mktemp -d) # Extract the original tar to a temp workspace tar -xf "$INPUT_TAR" -C "$TMP_DIR" # Navigate to the temp dir and generate a sorted file list by content MD5 cd "$TMP_DIR" sorted_files=$(find . -type f | while read file; do echo "$(md5sum "$file") $file" done | sort | cut -d' ' -f3-) # Re-pack the sorted files into a new tar, then compress with high-rate xz tar -cf - $sorted_files | xz -9 > "$OUTPUT_TXZ" # Cleanup temporary files and original tar rm -rf "$TMP_DIR" rm "$INPUT_TAR"
How This Works
- By sorting files by their MD5 hash, identical files (even in different paths) will be grouped consecutively in the new tar archive.
- XZ compression excels at compressing repeated content, so this grouping will drastically reduce the final archive size by eliminating redundant compressed data.
Windows Environment Note
If you're working on Windows, replace the bash script with a PowerShell equivalent. The core logic remains the same: extract, sort by file hash, re-pack, and compress.
内容的提问来源于stack exchange,提问作者TomTom

