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

2

6

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>
Vassallo answered 6/4, 2016 at 12:47 Comment(0)
E
7

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>
Eulogistic answered 6/4, 2016 at 12:52 Comment(3)
Do i lose the ability to write custom Assembly-Descriptors with the maven-shade-plugin?Vassallo
@replayleif what was your assembly descriptor customizing? can you add it to your question or at least its relevant part?Eulogistic
@replayleif check my edit, I've added required pointers and a sample to how to achieve the sameEulogistic
K
0

Also encountered this issue, my need was to filter out resource files of the same name from dependency modules, solution like below:

<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>
                        <filters>
                            <filter>
                                <artifact>artifact1</artifact>
                                <excludes>
                                    <exclude>application.yml</exclude>
                                    <exclude>logging.yml</exclude>
                                </excludes>
                            </filter>
                            <filter>
                                <artifact>artifact2</artifact>
                                <excludes>
                                    <exclude>application.yml</exclude>
                                    <exclude>logging.yml</exclude>
                                </excludes>
                            </filter>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.SF</exclude>
                                    <exclude>META-INF/*.DSA</exclude>
                                    <exclude>META-INF/*.RSA</exclude>
                                </excludes>
                            </filter>
                        </filters>
                    </configuration>
                </execution>
            </executions>
</plugin>

note the lines below is to avoid possible exception:

Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

<filter>
          <artifact>*:*</artifact>
          <excludes>
              <exclude>META-INF/*.SF</exclude>
              <exclude>META-INF/*.DSA</exclude>
              <exclude>META-INF/*.RSA</exclude>
          </excludes>
</filter>

In case you want more details, refer to Selecting Contents for Uber JAR

Krutz answered 21/11, 2016 at 13:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.