kelemen / netbeans-gradle-project

This project is a NetBeans plugin able to open Gradle based Java projects. The implementation is based on Geertjan Wielenga's plugin.
173 stars 57 forks source link

Build subproject with configuration in parent project fails #434

Closed cdalexndr closed 4 years ago

cdalexndr commented 4 years ago

I have a parent project that configures subprojects in "build.gradle" using:

subprojects {
...
}

Running build in a subproject with empty "build.gradle" (or none) fails with: Task 'check' not found in project ':parent:child'.

It seems that it searches only the current subproject for gradle build configuration, ignoring parent's.

kelemen commented 4 years ago

Empty build.gradle and non-existing might be different, because if you don't have build.gradle, then the directory might not register as a project directory. But if you have an empty build.gradle, then it is completely up to Gradle, how it evaluates scripts.

Not seeing your project, the only thing I can think of is that you have an extra settings.gradle in the directory of the subproject, or that the parent project is not in a parent directory. To validate that the issue is deterministic, put an empty build.gradle in the directory of the subproject, close NB, delete the cache in the .nb-gradle directory, and restart NB. But I'm guessing that you have some project configuration issue.

cdalexndr commented 4 years ago

Same behavior after following your steps with an empty 'build.gradle' Note that building from the parent project works and calls 'build' of subprojects. I have a settings.gradle at root that includes parent and subprojects.

After more playing around, it seems that the culprit is --configure-on-demand gradle argument. The following command fails in the subproject directory: ..\..\gradlew --configure-on-demand -x check build but the following works: ..\..\gradlew -x check build

cdalexndr commented 4 years ago

From docs: Configuration on demand .. only executes the build.gradle[.kts] file of projects that are participating in the build This seems inline with the observation that only the empty 'build.gradle' is used so the subproject isn't configured by the parent project, resulting in error.

Additional info for configuration on demand: The feature should work very well for multi-project builds that have decoupled projects.

Decoupled projects docs reference: Decoupled projects may only interact in terms of declared dependencies: project dependencies and/or task dependencies. A very common way for projects to be coupled is by using configuration injection.

Configuration injection docs reference The capability to configure a project build from any build script we call cross project configuration. Gradle implements this via configuration injection.

So because the subproject is configured by the parent project, configure on demand doesn't work. Shouldn't this incubating feature be removed until it becomes stable?

cdalexndr commented 4 years ago

Related gradle bugs: https://github.com/gradle/gradle/issues/12132 https://github.com/gradle/gradle/issues/11048

kelemen commented 4 years ago

I vaguely remember that somewhere in the Gradle doc it is (or used to be) defined that the build script evaluation order is parent first. Though now I can only find some old Gradle docs containing this (maybe I just did not look hard enough). That said, I agree that this is a very strange behavior, maybe I never came across this simply because I never liked the subprojects and allprojects blocks, even in the beginning when they were kinda promoted as a good practice.

Anyway, I'm closing this issue, since this is entirely with Gradle, so you should follow the issue you have linked.

cdalexndr commented 4 years ago

Note that continuing to use the incubating --configure-on-demand will break some builds, including mine.

cdalexndr commented 4 years ago

I use a parent project to configure common subprojects dependencies. Can you provide a workaround that doesn't involve duplicating the dependencies in each of subproject's build.gradle?

kelemen commented 4 years ago

I personally prefer to explictly apply a plugin defined in buildSrc in subprojects, but if you don't like that, then - given the issues you have linked - you should be able to put this configuration to the root project (since it seems that the root project is always evaluated), by opening blocks for the parent projects immediately below the root (and put your subprojects block there).

cdalexndr commented 4 years ago

Found how to disable --configure-on-demand, initially I thought it's a plugin embedded argument: Tools -> Options -> Java -> Gradle -> Execution -> Global Execution options -> uncheck "Configure on Demand" Problem solved.