Class: Cannot access configuration defined in one project from another project

I'm new to both gradle and groovy.

Problem

I have a very simple multi-project structure as shown below:

Root project 'gradle_test'
+--- Project ':sub1'
\--- Project ':sub2'

      

This is what the build.grade file looks like for the sub1 project :

// build.gradle of sub1 project
task testConfiguration {
    println project(':sub2').configurations.sub2FooConfiguration
}

      

And finally, it is a file 'build.grade' project sub2 :

// build.gradle of sub2 project
configurations {
    sub2FooConfiguration
}

      

Very minimal. Now if I run gradle :sub1:testConfiguration

I got the following error:

A problem occurred evaluating project ':sub1'.
> Could not find property 'sub2FooConfiguration' on configuration container.

      

However, everything works only if the task testConfiguration

in the sub1 project changes as follows:

// notice the "<<" (I believe this is calling the 'doLast' method on the task instance)
task testConfiguration << {
    println project(':sub2').configurations.sub2FooConfiguration
}

      

Question

I believe the difference between the two versions of the "testConfiguration" task is that in the first case the task is dispatched configuration closure

, whereas in the modified version the "normal" closure is passed to the "doLast" '.

So first, is my guess correct?

Second, why don't I have access to the "sub2" project in the first instance?

And finally, is it possible to access the "sub2" project in the first instance (ie when closing the config)?

[Update] Further question

Given the accepted answer "Invisible Arrow", I would like to ask one more question regarding the best practice of referencing the configuration of another project (ie the task in subsection 1 should use the archive created by the sub2 project),

Should I declare an estimate dependency between two projects?

Or should I only refer to the sub2 configuration at runtime (eg in doLast ())?

Or, should I create a dependency configuration between these two projects?

+3


source to share


1 answer


Yes, there is a difference between them. There are essentially 3 stages for a build: Initialization , Configuration and Execution . This is detailed in the Build Lifecycle chapter in the Gradle documentation.

In your case, the first instance belongs to the Configuration phase , which is always evaluated regardless of whether the job is running or not. This means that all instructions in the close are executed when the build starts.

task testConfiguration {
    // This always runs during a build,
    // irrespective of whether the task is executed or not
    println project(':sub2').configurations.sub2FooConfiguration
}

      

The second instance belongs to the Execution phase . Note that <<

is shorthand for doLast

, and this closure is called when the task is running.

task testConfiguration << {
    // Called during actual execution of the task,
    // and called only if the task was scheduled to be executed.
    // Note that Configuration phase for both projects are complete at this point,
    // which is why :sub1 is able to access :sub2 configurations.sub2FooConfiguration
    println project(':sub2').configurations.sub2FooConfiguration
}

      

Now that the first instance gave an error. This is because the Project Configuration phase sub2

has not yet been evaluated. Hence, it sub2FooConfiguration

has not yet been created.



Why? Because there is no explicit relationship between sub1

and sub2

. In your case, it sub1

needs sub2

evaluation as dependencies, so we can add this dependency sub1

build.gradle

before declaring the task as follows:

evaluationDependsOn(':sub2')
task testConfiguration {
    println project(':sub2').configurations.sub2FooConfiguration
}

      

This ensures that sub2

it is always evaluated before sub1

(evaluation means the Configuration stage for projects). sub1

will now be able to access the configurations.sub2FooConfiguration

closing task declaration. This is explained in detail in the chapter Multi-Project Builds .

In the second case, there was access configurations.sub2FooConfiguration

, since the call was in the task execution unit (which is after the Configuration phase for both projects).

PS . Please note, if you change the project names, then the first instance might work as Gradle sets up projects in alphabetical order if there are no explicit dependencies. But of course, you should never rely on this and ensure that dependencies between projects are explicitly declared.

+3


source







All Articles