Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api dependencies should have versions set, all others can use the bom #13812

Open
codeconsole opened this issue Oct 25, 2024 · 13 comments
Open

Comments

@codeconsole
Copy link
Contributor

Feature description

All dependencies with api need a version set or they end up with a pom with no version set.
All other dependencies that are in the bom do not need a version set.

@matrei
Copy link
Contributor

matrei commented Oct 25, 2024

All dependencies with api need a version set or they end up with a pom with no version set.

Is this documented somewhere, or could you give a more detailed explanation with examples of the cause and effect? I remember you mentioning (on Slack?) that this approach aligns with Spring's standard practices, so I'm sure it's correct, but I'd like to understand the reasoning behind it more clearly.

@jamesfredley
Copy link
Contributor

Example which includes the grails-bom:pom reference. The versions will not be applied unless called with platform

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-bom</artifactId>
        <version>7.0.0-SNAPSHOT</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

https://repo.grails.org/ui/repos/tree/PomView/libs-snapshots-local/org/grails/grails-shell/7.0.0-SNAPSHOT/grails-shell-7.0.0-20241024.195419-108.pom

@matrei
Copy link
Contributor

matrei commented Oct 26, 2024

To make this even clearer, an application without a BOM reference:

dependencies {
    implementation 'org.grails:grails-shell:7.0.0-SNAPSHOT'
}

yields (./gradlew dependencies):

compileClasspath - Compile classpath for source set 'main'.
\--- org.grails:grails-shell:7.0.0-SNAPSHOT
     +--- org.slf4j:slf4j-api FAILED
     +--- org.slf4j:jcl-over-slf4j FAILED
     +--- org.grails:grails-bootstrap:7.0.0-SNAPSHOT
     |    +--- org.slf4j:slf4j-api FAILED
     |    +--- org.slf4j:jcl-over-slf4j FAILED
     |    \--- org.yaml:snakeyaml FAILED
     +--- org.grails:grails-gradle-model:7.0.0-SNAPSHOT
     |    +--- org.slf4j:slf4j-api FAILED
     |    \--- org.slf4j:jcl-over-slf4j FAILED
     +--- org.apache.ant:ant FAILED
     +--- org.fusesource.jansi:jansi FAILED
     +--- jline:jline FAILED
     \--- org.springframework.boot:spring-boot-cli FAILED

while with a BOM reference:

dependencies {
    implementation platform('org.grails:grails-bom:7.0.0-SNAPSHOT')
    implementation 'org.grails:grails-shell:7.0.0-SNAPSHOT'
}

yields:

compileClasspath - Compile classpath for source set 'main'.
+--- org.grails:grails-bom:7.0.0-SNAPSHOT
|    +--- org.grails:grails-shell:7.0.0-SNAPSHOT (c)
|    +--- org.slf4j:slf4j-api:2.0.16 (c)
|    +--- org.slf4j:jcl-over-slf4j:2.0.16 (c)
|    +--- org.grails:grails-bootstrap:7.0.0-SNAPSHOT (c)
|    +--- org.grails:grails-gradle-model:7.0.0-SNAPSHOT (c)
|    +--- org.apache.ant:ant:1.10.15 (c)
|    +--- org.fusesource.jansi:jansi:1.18 (c)
|    +--- jline:jline:2.14.6 (c)
|    +--- org.springframework.boot:spring-boot-cli:3.3.5 (c)
|    \--- org.yaml:snakeyaml:2.2 (c)
\--- org.grails:grails-shell:7.0.0-SNAPSHOT
     +--- org.slf4j:slf4j-api -> 2.0.16
     +--- org.slf4j:jcl-over-slf4j -> 2.0.16
     |    \--- org.slf4j:slf4j-api:2.0.16
     +--- org.grails:grails-bootstrap:7.0.0-SNAPSHOT
     |    +--- org.slf4j:slf4j-api -> 2.0.16
     |    +--- org.slf4j:jcl-over-slf4j -> 2.0.16 (*)
     |    \--- org.yaml:snakeyaml -> 2.2
     +--- org.grails:grails-gradle-model:7.0.0-SNAPSHOT
     |    +--- org.slf4j:slf4j-api -> 2.0.16
     |    \--- org.slf4j:jcl-over-slf4j -> 2.0.16 (*)
     +--- org.apache.ant:ant -> 1.10.15
     |    \--- org.apache.ant:ant-launcher:1.10.15
     +--- org.fusesource.jansi:jansi -> 1.18
     +--- jline:jline -> 2.14.6
     \--- org.springframework.boot:spring-boot-cli -> 3.3.5

To use the Grails libraries without explicitly defining grails-bom as a platform in the application, we need to specify versions for dependencies in the Grails libraries that are included in the app’s compileClassPath.
Versions for runtime dependencies do not require this specification in the Grails libraries.

@jeffscottbrown
Copy link
Member

All dependencies with api need a version set or they end up with a pom with no version set.

Is it the case that this is only true for dependencies with api?

@codeconsole
Copy link
Contributor Author

@jeffscottbrown yes, it is only for situations where a project is not using the bom and trying to resolve the dependencies transitively. This won't happen for most applications because the grails-gradle-plugin automatically adds the bom.

@jeffscottbrown
Copy link
Member

yes

Thank you.

@jeffscottbrown
Copy link
Member

Is this a different problem?...

plugins {
    id 'java-library'
}

repositories {
    maven {
        url 'https://repo.grails.org/grails/core'
    }
}

dependencies {
    implementation 'org.grails:grails-bootstrap:7.0.0-SNAPSHOT'
}
Could not resolve all files for configuration ':lib:compileClasspath'.
   > Could not find org.slf4j:slf4j-api:.
     Required by:
         project :lib > org.grails:grails-bootstrap:7.0.0-SNAPSHOT:20241031.070243-121

@codeconsole
Copy link
Contributor Author

@jeffscottbrown it is the same problem, but it is happening because you are not using the grails-gradle-plugin. if you use the grails-gradle-plugin or add the bom to your project, you will not get the exception.

@jeffscottbrown
Copy link
Member

jeffscottbrown commented Nov 1, 2024

if you use the grails-gradle-plugin or add the bom to your project, you will not get the exception.

I misunderstood the bug report, but that clarity helps. It surprised me that this couldn't manifest with a dependency other than "api" so I tested it. Thank you.

@codeconsole
Copy link
Contributor Author

#13817 solves this issue and probably even probably fixes the @jeffscottbrown issue. @jeffscottbrown can you try running your example again with the latest snapshot?

@jeffscottbrown
Copy link
Member

@jeffscottbrown can you try running your example again with the latest snapshot?

I have run with the build file mentioned above and the compileJava task yields the following in my environment using Java 11:

> Task :lib:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':lib:compileJava'.
> Could not resolve all files for configuration ':lib:compileClasspath'.
   > Could not resolve org.grails:grails-bootstrap:7.0.0-SNAPSHOT.
     Required by:
         project :lib
      > No matching variant of org.grails:grails-bootstrap:7.0.0-SNAPSHOT:20241101.184847-123 was found. The consumer was configured to find an API of a library compatible with Java 11, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally but:
          - Variant 'apiElements' capability org.grails:grails-bootstrap:7.0.0-SNAPSHOT declares an API of a library, packaged as a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component compatible with Java 17 and the consumer needed a component compatible with Java 11
              - Other compatible attribute:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
          - Variant 'javadocElements' capability org.grails:grails-bootstrap:7.0.0-SNAPSHOT declares a runtime of a component, and its dependencies declared externally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 11)
                  - Doesn't say anything about its elements (required them preferably in the form of class files)
          - Variant 'runtimeElements' capability org.grails:grails-bootstrap:7.0.0-SNAPSHOT declares a runtime of a library, packaged as a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component compatible with Java 17 and the consumer needed a component compatible with Java 11
              - Other compatible attribute:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
          - Variant 'sourcesElements' capability org.grails:grails-bootstrap:7.0.0-SNAPSHOT declares a runtime of a component, and its dependencies declared externally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 11)
                  - Doesn't say anything about its elements (required them preferably in the form of class files)

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 8s
1 actionable task: 1 executed

With Java 17 compileJava appears to succeed.

@codeconsole
Copy link
Contributor Author

@jeffscottbrown Grails 7 required Java 17+ That is also the minimum requirement for Spring Framework 6

@codeconsole
Copy link
Contributor Author

I don't know if I like the bom api strategy. I think this might be better solved by adding the versions manually back in during pom generation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

4 participants