spring-gradle-plugins / dependency-management-plugin

A Gradle plugin that provides Maven-like dependency management functionality
690 stars 88 forks source link

Gradle 6.3: Publication only contains dependencies and/or constraints without a version #273

Closed flozano closed 4 years ago

flozano commented 4 years ago
* What went wrong:
Execution failed for task ':available-ports:generateMetadataFileForMavenJavaPublication'.
> Invalid publication 'mavenJava':
    - Publication only contains dependencies and/or constraints without a version. You need to add minimal version information, publish resolved versions (https://docs.gradle.org/6.3/userguide/publishing_maven.html#publishing_maven:resolved_dependencies) or reference a platform (https://docs.gradle.org/6.3/userguide/platforms.html)

I can't even see the generated POM :/

All the dependencies are managed thru importing a BOM. The generated POM with gradle 5.6.4 was:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.common.server</groupId>
  <artifactId>available-ports</artifactId>
  <version>999.2-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>mockito-all</artifactId>
          <groupId>*</groupId>
        </exclusion>
        <exclusion>
          <artifactId>servlet-api</artifactId>
          <groupId>javax.servlet</groupId>
        </exclusion>
        <exclusion>
          <artifactId>*</artifactId>
          <groupId>xerces</groupId>
        </exclusion>
        <exclusion>
          <artifactId>*</artifactId>
          <groupId>janino</groupId>
        </exclusion>
        <exclusion>
          <artifactId>*</artifactId>
          <groupId>commons-logging</groupId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.mycompany.platform</groupId>
        <artifactId>platform-common-parent</artifactId>
        <version>999.2-SNAPSHOT</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

There is nothing special in our application of the BOM:

    void apply(Project p) {
        p.dependencyManagement { dm ->
            String bomDependency = "com.mycompany.platform:platform-common-parent:${p.versionData.dependenciesVersion}"
            DependencyManagementBOMPlugin.logger.warn("Applying managed BOM to ${p.name} (${bomDependency})")
            dm.imports { mavenBom bomDependency }
        }
    }

(versionData is a property that contains version info, injected into the project from a different plugin. The expected log line appears, so I think that is not an issue:

Applying dependency-management to available-ports
Applying managed BOM to available-ports (`com.mycompany.platform:platform-common-parent:999.2-SNAPSHOT`)

)

wilkinsona commented 4 years ago

You need to do one of the three things that the exception message is suggesting:

You need to add minimal version information, publish resolved versions (https://docs.gradle.org/6.3/userguide/publishing_maven.html#publishing_maven:resolved_dependencies) or reference a platform (https://docs.gradle.org/6.3/userguide/platforms.html)

Of these three, publishing resolved versions is probably your best bet if you want to continue using the dependency management plugin:

publishing {
    publications {
        mavenJava(MavenPublication) {
            versionMapping {
                usage('java-api') {
                    fromResolutionOf('runtimeClasspath')
                }
                usage('java-runtime') {
                    fromResolutionResult()
                }
            }
        }
    }
}

Alternatively, you may want to consider using Gradle's platform support rather than this plugin.

flozano commented 4 years ago

Thanks for the quick message. However, when I do that, I get a different POM. All the managed dependencies which used to have empty <version/> tag, now they have the value resolved:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- This module was also published with a richer model, Gradle metadata,  -->
  <!-- which should be used instead. Do not delete the following line which  -->
  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
  <!-- that they should prefer consuming it instead. -->
  <!-- do_not_remove: published-with-gradle-metadata -->
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.common.server</groupId>
  <artifactId>available-ports</artifactId>
  <version>999.2-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>mockito-all</artifactId>
          <groupId>*</groupId>
        </exclusion>
        <exclusion>
          <artifactId>servlet-api</artifactId>
          <groupId>javax.servlet</groupId>
        </exclusion>
        <exclusion>
          <artifactId>*</artifactId>
          <groupId>xerces</groupId>
        </exclusion>
        <exclusion>
          <artifactId>*</artifactId>
          <groupId>janino</groupId>
        </exclusion>
        <exclusion>
          <artifactId>*</artifactId>
          <groupId>commons-logging</groupId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.mycompany.platform</groupId>
        <artifactId>platform-common-parent</artifactId>
        <version>999.2-SNAPSHOT</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

I want that version to come from the imported pom, which was the previous behavior.

flozano commented 4 years ago

I found out that if I fully disable gradle metadata generation, the old behavior can be kept:

        p.afterEvaluate { p1 -> 
            p1.tasks.withType(org.gradle.api.publish.tasks.GenerateModuleMetadata) {
                enabled = false
            }
        }

and the POM remains the same, without any explicit version mapping