When using the gradle plugin org.springframework.boot, it creates a configuration called developmentOnly and also changes the configuration runtimeClasspath to extend from developmentOnly.

Minimal example:

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.5.0'
}

dependencies {
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
    developmentOnly group: 'org.springframework.boot', name: 'spring-boot-devtools'
}

This effectively puts the devtools onto the runtime classpath, as can be verified by running ./gradlew -i dependencies --configuration runtimeClasspath.

We are building our projects as Docker images by using Google Jib. Jib blindly (but correctly) includes the complete runtimeClasspath into the image. This behavior is discussed here: * https://github.com/GoogleContainerTools/jib-extensions/pull/31#issuecomment-655553254 * https://github.com/GoogleContainerTools/jib/issues/2336

To exclude the devtools, there is an official jib extension: https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-spring-boot-extension-gradle . But this extension feels a bit cumbersome to use and really feels like a hacky workaround.

While researching other solutions to this issue, I've found out that the spring boot gradle plugin actually creates another gradle configuration called productionRuntimeClasspath that excludes the dependencies of the developmentOnly configuration. This is great and exactly what we need, because Jib can easily configured to use another configuration than runtimeClasspath.

Minimal example:

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.5.0'
    id 'com.google.cloud.tools.jib' version '3.0.0'
}

dependencies {
    implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}

dependencies {
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
    developmentOnly group: 'org.springframework.boot', name: 'spring-boot-devtools'
}

jib {
    configurationName = org.springframework.boot.gradle.plugin.SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME
    from {
        image = 'amazoncorretto:16'
    }
    to {
        image = 'myimage'
    }
}

As you can see, I reference org.springframework.boot.gradle.plugin.SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME as the configuration name that Jib should consume.

This works, because this is Groovy, and Groovy doesn't care about modifiers. In the source file at https://github.com/spring-projects/spring-boot/blob/47516b50c39bd6ea924a1f6720ce6d4a71088651/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java#L79, the constant is package private.

I hope that I could explain my use-case sufficiently. I think the constant PRODUCTION_RUNTIME_CLASSPATH_NAME should be made public. Other constants like BOM_COORDINATES are already public for (as I assume) similar reasons.

Comment From: philwebb

Thanks for the report. I agree that the constant should be public.

Comment From: ChristianCiach

Huh, that was surprisingly easy. One should keep in mind that this configuration is now public api, even though the plugin tried to hide it before:

https://github.com/spring-projects/spring-boot/blob/47516b50c39bd6ea924a1f6720ce6d4a71088651/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/JavaPluginAction.java#L222

Maybe the configuration productionRuntimeClasspath should even be properly documented now, maybe here: https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#reacting-to-other-plugins.java

Anyway, thank you for this quick response!

Comment From: philwebb

I missed that we previously kept the configuration open. I've flagged this issue for further team discussion because I'd like a second opinion on the change.

Comment From: ChristianCiach

Alright, thanks so far! I again want to stress the fact that there are real use cases for this configuration. Jib is hardly the only tool that consumes the runtimeClasspath configuration but would be better off consuming productionRuntimeClasspath.

Comment From: philwebb

We've decided to make the constant public but keep setVisible(false) so that the configuration isn't visible outside of the project it belongs to.