Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Gradle maven-publish dependency scope

I have a pretty simple Gradle Kotlin project.

plugins {
    id 'application'
    id 'maven-publish'
}

repositories { mavenCentral() }

dependencies {
     compile 'com.google.guava:guava:31.1-jre'      // 'compile' is deprecated
}

publishing {
    publications {
        maven(MavenPublication) {
            groupId = 'de.mabe'; artifactId = 'project1'; version = '1.0'
            from components.java
        }
    }
}

When I start gradle publishToMavenLocal it generates a correct pom file with a correct dependency:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
    <scope>compile</scope>             <!-- this scope is important -->
</dependency>

Now I replaced the compile with implementation in the gradle script.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

implementation 'com.google.guava:guava:31.1-jre'

Unexpectedly this changes the scope in the pom file from compile to runtime.

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
    <scope>runtime</scope>             <!-- compile EXPECTED ?!?! -->
</dependency>

What do I have to do to get the previous pom back?

>Solution :

That is by design. The semantics of the implementation configuration is to declare dependencies that are internal to a module. By mapping it to the runtime scope of a Maven pom, it ensures that it doesn’t leak onto the compilation classpath of consumers. This has a few advantages like being more free to swap out transitive depencies with less risk of affecting consuming modules, to make compilation faster and more.

If you need to make a transitive dependency part of the compile scope, i.e. expose it on the compilation classpath of consuming projects, you need to use the api configuration instead. This is available by applying the java-library plugin.

For example (Groovy DSL):

plugins {
    id 'java-library'
    id 'maven-publish'
}

dependencies {
    implementation 'org.apache.commons:commons-math3:3.6.1' // <- Maps to the Maven runtime scope 
    api 'com.google.guava:guava:30.1.1-jre' // <- Maps to the Maven compile scope
}

publishing {
    publications {
        maven(MavenPublication) {
            groupId = 'de.mabe'; artifactId = 'project1'; version = '1.0'
            from components.java
        }
    }
}

You can read more about the separation between API and implementation in the Gradle user guide here.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading