java.lang.IllegalStateException: The root project is not yet available for build.

I’m trying to set up my build to separate properties from the build code. Using the gradle.properties file to set some variables via Gradle’s Extra Property functionality for my multi-project build (need values to be visible to all sub-projetcts). My intent was to have things that could change between builds (i.e. developer setup structures, lib location differences, etc.) I’m assuming this is common practice, but not sure as I’m very new to gradle as well as build concepts as a whole.

gradle.properties:

glassfishHome = /glassfish
glassfishModules = /modules

settings.gradle:

include 'Project1'
gradle.rootProject.ext.gfModules = gfHome + glassfishModules

Then, my hope is any gradle.build file I have will be able to reference the variables directly as such

task printProps {
    println gfHome
    println gfModules
}

The stacktrace seems to indicate the projectRoot object is not yet ready from the settings.gradle. Am I missing a lifecycle concept or any other basic premise?

* Exception is:
org.gradle.api.GradleScriptException: A problem occurred evaluating settings 'Projects'.
 at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:54)
 at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:156)
 at org.gradle.initialization.ScriptEvaluatingSettingsProcessor.applySettingsScript(ScriptEvaluatingSettingsProcessor.java:69)
 at org.gradle.initialization.ScriptEvaluatingSettingsProcessor.process(ScriptEvaluatingSettingsProcessor.java:56)
 at org.gradle.initialization.PropertiesLoadingSettingsProcessor.process(PropertiesLoadingSettingsProcessor.java:36)
 at org.gradle.initialization.SettingsHandler.loadSettings(SettingsHandler.java:102)
 at org.gradle.initialization.SettingsHandler.findSettingsAndLoadIfAppropriate(SettingsHandler.java:93)
 at org.gradle.initialization.SettingsHandler.findAndLoadSettings(SettingsHandler.java:46)
 at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:134)
 at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:113)
 at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:81)
 at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:64)
 at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
 at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
 at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:35)
 at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:45)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:42)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:24)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.StartStopIfBuildAndStop.execute(StartStopIfBuildAndStop.java:33)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.ReturnResult.execute(ReturnResult.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:71)
 at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:69)
 at org.gradle.util.Swapper.swap(Swapper.java:38)
 at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:69)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:60)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:45)
 at org.gradle.launcher.daemon.server.DaemonStateCoordinator.runCommand(DaemonStateCoordinator.java:186)
 at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy.doBuild(StartBuildOrRespondWithBusy.java:49)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.HandleStop.execute(HandleStop.java:36)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.DaemonHygieneAction.execute(DaemonHygieneAction.java:39)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.CatchAndForwardDaemonFailure.execute(CatchAndForwardDaemonFailure.java:32)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
 at org.gradle.launcher.daemon.server.exec.DefaultDaemonCommandExecuter.executeCommand(DefaultDaemonCommandExecuter.java:51)
 at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.handleCommand(DefaultIncomingConnectionHandler.java:155)
 at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.receiveAndHandleCommand(DefaultIncomingConnectionHandler.java:128)
 at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.run(DefaultIncomingConnectionHandler.java:116)
 at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
Caused by: java.lang.IllegalStateException: The root project is not yet available for build.
 at org.gradle.invocation.DefaultGradle.getRootProject(DefaultGradle.java:112)
 at org.gradle.invocation.DefaultGradle_Decorated.getRootProject(Unknown Source)
 at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.getProperty(BeanDynamicObject.java:158)
 at org.gradle.api.internal.BeanDynamicObject.getProperty(BeanDynamicObject.java:112)
 at org.gradle.api.internal.CompositeDynamicObject.getProperty(CompositeDynamicObject.java:78)
 at org.gradle.invocation.DefaultGradle_Decorated.getProperty(Unknown Source)
 at settings_71i4riranb3dhub5smvis0r0q6.run(/Users/user/apps/Projects/settings.gradle:2)
 at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:52)
 ... 52 more

After tons of trial and error/more research, the following is how I was able to get this to work:

settings.gradle

include 'Project1'
gradle.ext.gfModules = gradle.gfHome + glassfishModules

Once set via this syntax, from any sub-project(s), the extra properties can be referenced normally.

println gfModules

Hope this helps anybody struggling with a similar issue.

I have not idea how or why, but the described fix above stopped working. For some reason, this worked for about day (sounds crazy I know). Now, anywhere I want to reference the extra property I have to do so like this:

println gradle.gfModules

Any direction to fix this would be awesome. From all my reading I was under the impression one could call any extra property by name and not need ‘gradle.foo’ or ‘gradle.ext.foo’. I’m just confused on why the ‘gradle.foo’ seems to be required.

I can’t find any indication in the docs that ‘gradle.’ can be omitted (only ‘project.’ and ‘rootProject.’ can), and I can’t reproduce it either. To investigate further, we’d need a minimal reproducible example that proves that it can be omitted.

From your examples, it’s not clear to me why you are defining the property in ‘settings.gradle’. Instead, I’d define it in the root build script, or in an entirely separate build script that gets applied with ‘apply from:’ in the root build script (and if necessary, also in ‘settings.gradle’). You might also want to move over user-defined properties from ‘gradle.properties’, to have everything in one place/language.

PS: ‘ext’ should only be used when defining extra properties, not when reading them.

The only driving force as to why I was using the settings.gradle file is because I’m using my gradle. properties as the file I want my team to modify per their local instance (i.e. they’ve created a different location to house the glassfish libs, etc.) I wanted the build file(s) to be set, and any modifications would only need to be changed in the properties file. I was thinning about the extra properties as “settings” to the project, but I do like what you recommend and simply using the

apply from:

method and simply include an additional build file. This would accomplish what I want too.

Just for my education. I’m reading the book, Gradle in Action MEAP, and multiple places state when setting extra properties that you should not use the ext when reading, only when defining (as you had indicated). I was trying this, but was not having any luck. It was only until I started using the ‘gradle.xyz’ that I was able to read. You did, however; say something that caught my attention. “I can’t find any indication in the docs that gradle. can be omitted (only project. and rootProject. can)”. This made me realize that rootProject/project properties are different that that of gradle properties. I was simply interpreting the words ‘gradle extra properties’ to mean properties defined from either the rootProject or project. If you would, could you explain the difference here so I can ensure I get it.

All and all, I just want to be able to set the vales in the gradle.properties file into variables that can be read from any of the sub-projects. Any suggestions on how to best accomplish this would rock!

Thanks again Peter for your time!

This made me realize that rootProject/project properties are different that that of gradle properties.

I think we are talking cross purposes here. What I said is that I don’t think you can ever leave off ‘gradle.’ when accessing predefined or extra properties on the ‘gradle’ object. However, you can leave off ‘project.’ when accessing predefined or extra properties on the ‘project’ object, and the search will also continue in parent projects. See ‘Project’ in the Gradle Build Language Reference for details.

All and all, I just want to be able to set the vales in the gradle.properties file into variables that can be read from any of the sub-projects.

The properties defined in ‘gradle.properties’ can be accessed from build scripts out of the box. If you want to compute derived properties, do so in the root ‘build.gradle’ rather than in ‘settings.gradle’ (‘ext.foo = …’). Other build scripts can then access these properties by their simple name.