Skip to content

Devtools documentation incorrectly uses compileOnly Gradle scope #14451

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

Closed
douglyuckling opened this issue Sep 12, 2018 · 8 comments
Closed

Devtools documentation incorrectly uses compileOnly Gradle scope #14451

douglyuckling opened this issue Sep 12, 2018 · 8 comments
Assignees
Labels
type: documentation A documentation update
Milestone

Comments

@douglyuckling
Copy link

The Developer Tools section of the documentation says:

... using compileOnly in Gradle is a best practice that prevents devtools from being transitively applied to other modules that use your project.

But the compileOnly configuration doesn't work for devtools, as noted by @wilkinsona in his comment on spring-io/initializr#128.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 12, 2018
@philwebb philwebb assigned philwebb and unassigned philwebb Sep 12, 2018
@philwebb philwebb added type: documentation A documentation update and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 12, 2018
@philwebb philwebb added this to the 2.0.x milestone Sep 12, 2018
@wilkinsona
Copy link
Member

Well spotted, @douglyuckling . If only I'd remembered what I said in November 2016 when changing the docs in March 2018.

@wilkinsona
Copy link
Member

wilkinsona commented Sep 13, 2018

Unfortunately, I don't think Gradle has a built-in configuration that meets our needs and I'm reluctant to start recommending the propdeps plugin again. I've asked on the Gradle Slack channel to see if that's anything I'm not aware of. If there is not then, given that we don't encourage people using a Spring Boot application as a dependency anyway, I'm tempted to just recommend that people use compile.

@douglyuckling
Copy link
Author

Yeah, I had a feeling this wouldn't simply be a documentation fix. 😉

I'm sure you'll get a good answer from the folks on the Gradle Slack channel, but here's my unsolicited opinion anyway:

I think it would make sense for the Gradle plugin to add a custom configuration called bootRunOnly that extends the runtimeClasspath configuration, and have the bootRun task use that configuration for its classpath (instead of runtimeClasspath). The "best practice" would be to add devtools to the bootRunOnly configuration. If users wanted to include devtools in the JAR they would want to add it to the runtime configuration instead (it's not actually used at compile time, right?) in addition to setting excludeDevtools = false.

(And my apologies if that solution has previously been proposed and rejected for some reason. I haven't researched the issue deeply.)

@wilkinsona
Copy link
Member

Thanks for the suggestion. I'd considered customising the classpath of bootRun. Unfortunately it won't work well in an IDE when the main method is launched directly as it'd lose DevTools.

Daz DeBoer on the Gradle team has suggested a refinement though by inverting the extension. It looks as if a custom configuration that runtimeClasspath extends from may work. I'll need to do some experimenting when I get some time.

@wilkinsona
Copy link
Member

Daz's suggestion appears to work nicely. With a custom configuration set up like this:

configurations {
	developmentOnly
	runtimeClasspath {
		extendsFrom developmentOnly
	}
}

And a dependency on DevTools declared like this:

dependencies {
    developmentOnly('org.springframework.boot:spring-boot-devtools')
}

This setup also has the advantage that DevTools doesn't end up on the test classpath (#5307) so in that respect the name developmentOnly is quite accurate. It's inaccurate in that bootJar still needs excludeDevtools = true to not package it so we might need to think of a better name.

@douglyuckling
Copy link
Author

If it's important that DevTools ends up in runtimeClasspath, then it's not clear to me how a custom configuration would be helpful. Adding the dependency directly to the runtimeOnly configuration would achieve the same result, no?

Unfortunately it won't work well in an IDE when the main method is launched directly as it'd lose DevTools.

True, but I'll point out that launching the main class directly from the IDE also doesn't get the classpath modifications made by sourceResources. Also, shouldn't it be the IDE's job to support alternative classpaths provided by the build tool, not the build tool's job to make sure everything the user could ever want is in the one and only classpath supported by the IDE? In any case, if a user really wanted DevTools to be available when launching from an IDE they could always add it to the runtimeOnly configuration instead.

@wilkinsona
Copy link
Member

Adding the dependency directly to the runtimeOnly configuration would achieve the same result, no?

It would not. runtimeOnly dependencies end up on the test runtime classpath and are also pulled in transitively if another project depends on the project with the runtimeOnly dependency in it.

True, but I'll point out that launching the main class directly from the IDE also doesn't get the classpath modifications made by sourceResources

Indeed not, but that's not necessary when you're using an IDE as it'll "build" any changes to the resource so the DevTools finds them anyway.

Also, shouldn't it be the IDE's job to support alternative classpaths provided by the build tool, not the build tool's job to make sure everything the user could ever want is in the one and only classpath supported by the IDE?

No, I don't think so. If we can provide something that fits into the existing model that's served IDEs well, we won't place an unnecessary burden on the IDEs' developers and users will be able to use the new functionality as soon as we ship it, rather than waiting for a new version of their IDE to be available and for them to be able to upgrade to it.

@douglyuckling
Copy link
Author

It would not. runtimeOnly dependencies end up on the test runtime classpath and are also pulled in transitively if another project depends on the project with the runtimeOnly dependency in it.

Ah, my apologies. I was thinking that runtimeClasspath was the basis for testRuntimeClasspath and for what would be inherited transitively. But now having studied the relationships among the configurations carefully, I see that actually nothing inherits from runtimeClasspath. So indeed Daz's suggestion seems great.

Indeed not, but that's not necessary when you're using an IDE as it'll "build" any changes to the resource so the DevTools finds them anyway.

Oh, right, of course. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation A documentation update
Projects
None yet
Development

No branches or pull requests

4 participants