Gradle 6.4.1 appears to have broken parts of the "shadow" plug-in

When using the “shadow” plug-in with Gradle 6.4.1 it appears to be impossible to configure the “shadowRun” task. See this issue for more details, but this appears to be related to a definition change in JavaApplication between 6.3 and 6.4 (the property “mainClassName” was removed and setting it produces an error). Any pointers on how we might work around the apparent catch-22 of this would be appreciated. I’m also curious if this kind of change is common for a “minor” release.

TIA for any help/insight.


The property mainClassName was not removed. The convention property directly on the project is deprecated, but the replacement mainClassName property is available on the application extension. They’re actually the exact same instance, so there’s no difference in behavior until the plugin stops adding the deprecated convention (likely in a major version). This is not what’s causing your issue.

The introduction of the mainClass property on the task is an implementation detail of the task. It was added, but the existing APIs were also not changed in a backwards incompatible way and does not impact what you should be configuring in the application extension. It’s still mainClassName, just project.application.mainClassName instead of project.mainClassName (extension vs. convention). This is also not what’s causing your issue (at least directly).

So, what’s actually causing the issue? It’s the fact that the Shadow plugin is relying on behavior that’s technically not safe or supported, but the underlying implementation details didn’t cause an issue until now. The plugin has a custom task type that extends a built-in Gradle task. The custom task type (which it would be fine without) tries to modify the configuration of the task (itself) after execution has already begun. It was possible to get away with it before, but now that the implementation uses a Property it is not possible to modify the value once it has been finalized. That’s what the error is stating.

If you want to work around this until it is fixed, nothing stops you from declaring your own JavaExec task that has the options from shadowRun copied as well as setting the main to -jar in your configuration rather than waiting until execution time.

So, yes, these kind of implementation detail changes are fairly common in a “minor” release. The public API is stable and backward compatible. Plugins do break on minor versions though when they try to get too clever and rely on implementation details.

Thanks for the report.

From looking at the shadow code, there is no way to work around this aside from using a different setup to run the JAR produced by shadow.

On the issue filed on shadow, I have added a snippet showing how to declare a task which would behave similarly to what runShadow does but works with Gradle 6.4+