mavenpom.xmlscopes

Pom type imported dependency cannot be used without version


I have a project with two modules. The core module has the following in pom:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>project.X</groupId>
            <artifactId>project_X</artifactId>
            <version>42</version>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

this dependency on pom declared without scope import

and second module of the same project has the following:

    <dependencies>
        <dependency>
            <groupId>project.X</groupId>
            <artifactId>project_X</artifactId>
            <type>pom</type>
        </dependency>
    </dependencies>

And all of this works fine, but if I put import in the core pom like this:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>project.X</groupId>
            <artifactId>project_X</artifactId>
            <version>42</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

then the second module will not compile due to the dependency has no version declared. But, as far as I understand, it should compile with scope import in the root module and should NOT compile if vice versa. Does anybody has any idea of the reason of such behaviour?

Thanks.


Solution

  • Does anybody has any idea of the reason of such behaviour?

    That is how the feature was implemented over 15 years ago:

    @SuppressWarnings("checkstyle:methodlength")
    private void importDependencyManagement(
            Model model,
            ModelBuildingRequest request,
            DefaultModelProblemCollector problems,
            Collection<String> importIds) {
        DependencyManagement depMgmt = model.getDependencyManagement();
    
        if (depMgmt == null) {
            return;
        }
    
        String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
    
        importIds.add(importing);
    
        final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
        final ModelResolver modelResolver = request.getModelResolver();
    
        ModelBuildingRequest importRequest = null;
    
        List<DependencyManagement> importMgmts = null;
    
        for (Iterator<Dependency> it = depMgmt.getDependencies().iterator(); it.hasNext(); ) {
            Dependency dependency = it.next();
    
            if (!"pom".equals(dependency.getType()) || !"import".equals(dependency.getScope())) {
                continue;
            }
    
            //
            // Here it removes managed dependency on BOM
            //
            it.remove();
    
            String groupId = dependency.getGroupId();
            String artifactId = dependency.getArtifactId();
            String version = dependency.getVersion();
    

    and I do believe the current implementation is in sync with documentation:

    Imports are most effective when used for defining a "library" of related artifacts that are generally part of a multiproject build. It is fairly common for one project to use one or more artifacts from these libraries. However, it has sometimes been difficult to keep the versions in the project using the artifacts in synch with the versions distributed in the library. The pattern below illustrates how a "bill of materials" (BOM) can be created for use by other projects.

    The root of the project is the BOM POM. It defines the versions of all the artifacts that will be created in the library. Other projects that wish to use the library should import this POM into the dependencyManagement section of their POM

    since you are not supposed to define dependencies (only versions, i.e. managed dependencies) in BOM's, defining dependency on BOM does not make any sense.