leimooo leimooo - 11 days ago 5
Java Question

files from different maven-modules with the same name can not co-exist in a jar-file created with the maven assembly-plugin

If there are two files with different content but with the same name in two different maven-modules, wich are both put together in one jar-file with the maven assembly-plugin, only one file ends up being part of the .jar file.

Question: Is there a way to ensure that the content of the files is assembled into one file when building the jar-file?

I obviously do not want to put the information together manually, since this is what I am trying to avoid by splitting the project in different modules.

EDIT: I have a custom Assembly-Descriptor that i would like to keep, even if I start using another plugin. This Descriptor basically excludes every language but the english one for resources and error-texts.

<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
<unpackOptions>
<excludes>
<exclude>**/*Resources_*</exclude>
<exclude>**/*ErrorsText_*</exclude>
</excludes>
</unpackOptions>
</dependencySet>
</dependencySets>

Answer

As specified by the maven-assembly-plugin documentation:

If your project wants to package your artifact in an uber-jar, the assembly plugin provides only basic support. For more control, use the Maven Shade Plugin.


Using the maven-shade-plugin you can have a fat jar (like using the assembly plugin) and solve similar issues of merging file using Resources transformers. In your case, the AppendingTransformer would merge files with the same name but with different content.

Some jars contain additional resources (such as properties files) that have the same file name. To avoid overwriting, you can opt to merge them by appending their content into one file.

A simple configuration would look like:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>path/to/file/file-name-here</resource>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Update
You don't need an external assembly descriptor for the shade plugin, you can configure your requirements directly as plugin configuration.
In your case, to exclude resources from assembled jars, you can use shade filters.

A simple configuration (to be merged with the one above) would look like:

<configuration>
    <filters>
        <filter>
            <artifact>*:*</artifact>
            <excludes>
                <exclude>**/*Resources_*</exclude>
                <exclude>**/*ErrorsText_*</exclude>
            </excludes>
        </filter>
    </filters>
</configuration>
Comments