Pass dynamic arguments to a plugin

I am a new Gradle user, and have a Gradle plugin which uses another plugin as below:

build.gradle

class GreetingPluginExtension {
    String message
}

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.plugins.apply('org.some.otherplugin')
        def extension = project.extensions.create('greet', GreetingPluginExtension)

        project.release {
            println "Message = ${extension.message}"
            def foo = new MyCustomClass(extension.message)
            foo.someReleaseFunction()
        }
    }
}

apply plugin: GreetingPlugin

greet.message = 'Hello Gradle'

I always get a Message = null when I run ./gradlew release. How can I pass a value that I can use in project.release?

All code in the apply(Project project) method of the plugin executes on the apply plugin: GreetingPlugin line, which includes the println, so you’re printing the message the line before you set greet.message.

You need to defer evaluation of your extension property until later. If the other plugin supports it, use Property<String> instead of just String. Otherwise, execute your code first in a task action (doFirst { }), a separate task, or as a last resort, afterEvaluate { }.

Got it, makes sense, thanks! So in case of using a Property<String>, how would I pass it in without having to use a task. Will it be
project.setProperty('message', "value of the message") ?

It’s unclear for your case. It’s largely dependent on what is supported by what you’re using that is out of your control. My expectation is that the release task is added by org.some.otherplugin and that you can’t change its code.

Also, the code shown doesn’t really indicate what how MyCustomClass and someReleaseFunction() are interacting with the release task. Typically you would be setting properties on that release task that would be used when it executes. The type of the properties on the release task would determine what you can do with a Property<String> from your extension. If your someReleaseFunction() is actually doing work, not configuring the release task, then there’s a fundamental configuration time vs. execution time issue with your code that needs to be resolved first.

It’s largely dependent on what is supported by what you’re using that is out of your control. My expectation is that the release task is added by org.some.otherplugin and that you can’t change its code.

and

Also, the code shown doesn’t really indicate what how MyCustomClass and someReleaseFunction() are interacting with the release task.

Yes, you are completely right. There is an weaving of a few projects at different levels, and its hard to simplify that into an example I can put on here. There is a particular case, when a specific variable is not set, and that is the failure case I am trying to address.
I just found out about https://docs.gradle.org/4.9/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html
I just added project.ext.set(keyString, valueString) before the apply plugin, it does solve the problem.
Thanks for the help!