How to have maven-assembly-plugin respect the exclusions defined in pom.xml?

Use the maven-dependency-plugin

Though not the ultimate solution I am looking for, this may help people who are in an emergency.

pom.xml

In your POM, define the following property (adapt the path to your preferences):

<properties>
    <!-- ... -->
    <assembly.lib.directory>${project.build.directory}/lib</assembly.lib.directory>
    <!-- ... -->
</properties>

In the <build/> section:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${assembly.lib.directory}</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                        <prependGroupId>true</prependGroupId>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptors>
                    <descriptor>src/main/assembly/assembly.xml</descriptor>
                </descriptors>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

assembly.xml

The idea is replacing the dependencySet with a fileSet:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>bin</id>
    <formats>
        <format>zip</format>
    </formats>

    <!-- Adds dependencies to zip package under lib directory -->
    <fileSets>
        <fileSet>
            <directory>${assembly.lib.directory}</directory>
            <outputDirectory>lib</outputDirectory>
        </fileSet>

        <!-- ... -->
    </fileSets>
</assembly>

Edit: as highlighted by user716401, it is better to execute the dependencies:copy-dependencies in prepare-package phase to ensure it runs before assembly:single.


Edit

Version 3.1.1 of the maven-assembly-plugin have been released Jan 01, 2019. It solves the JIRA issues mentioned in my answer below (kept for history or for users that cannot upgrade the plugin). With this version, maven-assembly-plugin now honors wildcards in dependencies exclusions. Simply upgrade the plugin.

Answer for maven-assembly-plugin version <= 3.1.0

It appears that Maven assembly plugin (version <= 3.1.0) does not honor exclusions using wildcards (*), see MASSEMBLY-762, MASSEMBLY-861 or MASSEMBLY-675. From the last JIRA issue, the problem will be solved in version 3.1.1 of the plugin (see commit). At the moment of writing, the 3.1.1 version is not released : 3.1.0 is the latest version.

Hopefully, the problem can be solved with version <= 3.1.0.

To do so, just declare the right excluded artifacts instead of *, and it works properly. It can be painful to list all excluded dependencies, but at least I think it is a better solution than the accepted one (less tweaking of Maven phases), especially on multi-modules project with cross dependencies (my case). Moreover, by doing so, you have more control about the dependencies.

Hope that helps, waiting the 3.1.1 version! :)