Maven 2.x Assembly Plugin

Multiple inclusion of dependencies in binary assembly

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Duplicate
  • Affects Version/s: 2.2-beta-2
  • Fix Version/s: 2.2-beta-3
  • Component/s: None
  • Labels:
    None
  • Environment:
    all
  • Number of attachments :
    0

Description

Hello,

today I tried to upgrade the Maven assembly plugin from 2.2-beta-1 to 2.2-beta-2. However, I noticed that for my project which consists of multiple modules the resulting binary assembly now contains dependency JAR files multiple times. The assembly descriptor contains the following excerpt (with changed module names):

<moduleSets>
<moduleSet>
<includes>
<include>${pom.groupId}:a</include>
<include>${pom.groupId}:b</include>
<include>${pom.groupId}:c</include>
</includes>
<binaries>
<includeDependencies>true</includeDependencies>
<unpack>false</unpack>
<outputDirectory>/lib</outputDirectory>
</binaries>
</moduleSet>
</moduleSets>

The projects a, b, c have several dependencies, whereby some of those dependencies refer to identical artifacts (derived from a parent POM), e.g., commons-logging. The resulting ZIP and TAR.GZ assembly files then contain those dependencies multiple times (in the lib folder) with equal names! Im not sure if this is a bug or a feature and I might have missed something.

I rolled back to version 2.2-beta-1 and I could reproduce the issue. 2.2-beta-1 works as expected, i.e., all files exist only once.

Regards,
Thorsten

Issue Links

Activity

Hide
Rainer Meier added a comment -

I can confirm this report. I faced exactly the same problem here. It seems that the assembly plugin (version 2.2-beta-2) just adds the whole dependency tree of each module to the archive. This results in duplicated inclusion of dependencies (even if the version is exactly the same, enforced by parent POM).

The only way to avoid this problem is to use an archive format which does not support adding the same file twice to an identical directory. The only archive format I found is 'dir'. All others will include the dependencies multiple times and therefore growing the archive.

I can confirm too that version 2.2-beta-1 behaves differently (probably it's writing the dependencies to a directory before adding to archive).

In general I think it's true that inclusion of dependencies are somehow a problem. Especially the results are undefined if multiple modules are depending on the same artifact but use different versions. But such issues should be addressed by enforcing dependency versions within the parent POM. Unfortunately the problem applies to "dependencies of dependencies" as well and therefore dependency A might depend on artifact-a version 1.0 and dependency B might depend on artifact-a version 1.1. Which one to include?

In such case I think the assembly plugin should include artifact-a version 1.0 as well as version 1.1 (probably a switch/parameter to include only latest version would be possible too). A warning about such conflicts might be printed (same artifact with different version within the dependency tree). I know that currently a similar message is displayed:

[WARNING] NOTE: Currently, inclusion of module dependencies may produce unpredictable results if a version conflict occurs.

But instead of such a generic message a message about a concrete conflict (same artifact, different version) might be displayed. In case it is possible to determine which of the conflicting versions is the latest one, then a configuration switch might allow to include the latest version only. In most cases this will solve the conflict and later versions are backwards compatible in lots of cases.
For example:

[WARNING] Dependency version conflict: Module X depends on artifact-a version x.y while Module Y depends on artifact-a version v.w. Including both.

or

[WARNING] Dependency version conflict: Module X depends on artifact-a version x.y while Module Y depends on artifact-a version v.w. Including version x.y (latest) only.

Show
Rainer Meier added a comment - I can confirm this report. I faced exactly the same problem here. It seems that the assembly plugin (version 2.2-beta-2) just adds the whole dependency tree of each module to the archive. This results in duplicated inclusion of dependencies (even if the version is exactly the same, enforced by parent POM). The only way to avoid this problem is to use an archive format which does not support adding the same file twice to an identical directory. The only archive format I found is 'dir'. All others will include the dependencies multiple times and therefore growing the archive. I can confirm too that version 2.2-beta-1 behaves differently (probably it's writing the dependencies to a directory before adding to archive). In general I think it's true that inclusion of dependencies are somehow a problem. Especially the results are undefined if multiple modules are depending on the same artifact but use different versions. But such issues should be addressed by enforcing dependency versions within the parent POM. Unfortunately the problem applies to "dependencies of dependencies" as well and therefore dependency A might depend on artifact-a version 1.0 and dependency B might depend on artifact-a version 1.1. Which one to include? In such case I think the assembly plugin should include artifact-a version 1.0 as well as version 1.1 (probably a switch/parameter to include only latest version would be possible too). A warning about such conflicts might be printed (same artifact with different version within the dependency tree). I know that currently a similar message is displayed: [WARNING] NOTE: Currently, inclusion of module dependencies may produce unpredictable results if a version conflict occurs. But instead of such a generic message a message about a concrete conflict (same artifact, different version) might be displayed. In case it is possible to determine which of the conflicting versions is the latest one, then a configuration switch might allow to include the latest version only. In most cases this will solve the conflict and later versions are backwards compatible in lots of cases. For example: [WARNING] Dependency version conflict: Module X depends on artifact-a version x.y while Module Y depends on artifact-a version v.w. Including both. or [WARNING] Dependency version conflict: Module X depends on artifact-a version x.y while Module Y depends on artifact-a version v.w. Including version x.y (latest) only.
Hide
John Casey added a comment -

If you're talking about adding the exact same dependency artifacts to the exact same path within the archive several times, then it would be a great help to get a test project that expresses this problem. If you could attach one, that would help to illuminate this problem...if this is the case, I suspect it's related to another issue we solved for 2.2-beta-3: MASSEMBLY-285.

Otherwise, it's perfectly reasonable to assume that when constructing an assembly, modules should have all included dependencies added to their respective locations within the archive, without editing them for duplicates automatically. If you're constructing something like an EAR using the assembly plugin, perhaps you should create a common location for these dependencies, and exclude them from the other modules' dependencySets? Surely you can see that editing for duplicates automatically will affect other legitimate use cases, where users will have no control at all over what module dependencies land where...

Show
John Casey added a comment - If you're talking about adding the exact same dependency artifacts to the exact same path within the archive several times, then it would be a great help to get a test project that expresses this problem. If you could attach one, that would help to illuminate this problem...if this is the case, I suspect it's related to another issue we solved for 2.2-beta-3: MASSEMBLY-285. Otherwise, it's perfectly reasonable to assume that when constructing an assembly, modules should have all included dependencies added to their respective locations within the archive, without editing them for duplicates automatically. If you're constructing something like an EAR using the assembly plugin, perhaps you should create a common location for these dependencies, and exclude them from the other modules' dependencySets? Surely you can see that editing for duplicates automatically will affect other legitimate use cases, where users will have no control at all over what module dependencies land where...
Hide
Paul Gier added a comment -

I just ran into this issue, and I can confirm that it can be fixed using the same archiverConfig configuration described in MASSEMBLY-285.
Can we change the default behavior of the assembly plugin? It seems like it makes more sense to not allow duplicates by default. Especially since, as Rainer described, the "dir" format will not include duplicates and you can end up with different contents for "dir" vs. "zip" for example.

Show
Paul Gier added a comment - I just ran into this issue, and I can confirm that it can be fixed using the same archiverConfig configuration described in MASSEMBLY-285. Can we change the default behavior of the assembly plugin? It seems like it makes more sense to not allow duplicates by default. Especially since, as Rainer described, the "dir" format will not include duplicates and you can end up with different contents for "dir" vs. "zip" for example.
Hide
John Casey added a comment -

My understanding of this issue is that it duplicates MASSEMBLY-285. If this is not the case, please reopen the issue.

Show
John Casey added a comment - My understanding of this issue is that it duplicates MASSEMBLY-285. If this is not the case, please reopen the issue.

People

Vote (4)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: