FAILURE: Build failed with an exception. * What w...
# community-support
u
FAILURE: Build failed with an exception. * What went wrong: A problem occurred configuring project ':app'.
Failed to notify project evaluation listener.
> java.lang.IllegalStateException: Cannot change attributes of configuration 'appreleaseUnitTestCompileClasspath' after it has been locked for mutation > KotlinJvmAndroidCompilation with name 'releaseUnitTest' not found.
Copy code
class PluginMain:Plugin<Project> {

    override fun apply(target: Project) {
        soSearch(project = target)
    }

    private fun soSearch(project: Project){


        val appExtension = project.extensions.getByType(AppExtension::class.java)
        appExtension.applicationVariants.all{
            val applicationVariants = this.name
            System.err.println("applicationVariants $applicationVariants")
            val configuration = project.configurations.getByName(applicationVariants + "CompileClasspath")
            println("SoPlugin applicationVariants $applicationVariants")
            configuration.forEach { file ->
                println("SoPlugin" + "file " + file.name)
                val fineName = file.name
                if (fineName.endsWith(".jar") || fineName.endsWith(".aar")) {
                    try {
                        val jarFile = JarFile(file)
                        val enums: Enumeration<*> = jarFile.entries()
                        while (enums.hasMoreElements()) {
                            val jarEntry: JarEntry = enums.nextElement() as JarEntry
                            if (jarEntry.name.endsWith(".so")) {
                                println("SoPlugin" + "----soEntry " + jarEntry.name)
                            }
                        }
                    } catch (e: IOException) {
                        // throw RuntimeException(e)
                    }
                }
            }
        }
    }
}
v
Is there a question hidden somewhere? :-)
1
u
resolve the problem
Copy code
target.afterEvaluate {
    soSearch(this)
}
v
That's practically never a solution, but duct tape. The main effect of
afterEvaluate
is to introduce timing problems, ordering problems, and race conditions. It is like using
SwingUtilities.invokeLater
or
Platform.runLater
to "fix" a GUI problem. It just does symptom treatment, delaying the problem to a later, harder to reproduce, harder to debug, and harder to fix point in time.
u
may be the problem is gradle required
v
I neither understood that sentence, nor do I now see a question. Just an error pasted. If you don't formulate a question, people have to guess what you want to know and that might easily lead to miscommunication and wasted time.
u
the error is gradle runtime error. the plugin run at a wrong time. this from GPT : The error message "Cannot change attributes of configuration 'appreleaseUnitTestCompileClasspath' after it has been locked for mutation" typically occurs in Gradle when you attempt to modify a configuration after it has already been resolved or during a phase where it should not be modified. This can happen in various scenarios, such as adding dependencies, modifying attributes, or changing the configuration's properties in the wrong build phase.
thanks
v
You're welcome
But you still did not ask any question
As the error and your duct tape solution tell you, you are resolving the configuration too early. But what is your question?
u
I happen to the error, I don't understand and can't resloved the error . so send the error message. Now the error is resolved and I know why the error happen
v
As I said, if you use
afterEvaluate
the error is not solved, just made more fragile
What is the use-case of that code? Just to do some
println
statements? Why do they need to be done at configuration time?
u
any suggestion ?
v
Sure, I suggest you answer my questions. 🙂
u
this is my plugin code
v
Please never share screenshots of code anywhere except if you want to show additional things like IDE annotations or similar. They are hard to read - especially on mobile -, very hard to copy from, and almost impossible to search for. If it is only for the text, please share the text with proper markup.
Besides that it does not answer any of my questions
u
I understand the apply from plugin run at Gradle config step. so some code can't run and gradle send a exception . after configure done . My code can work
v
Again,
afterEvaluate
is not after configuration it is still during configuration, and there can still things be done later that make it fail again, you just make your code less reliable, more buggy, more flaky, and more bad-practice.
If you want help, please answer the questions you are asked
u
FAILURE: Build failed with an exception. * What went wrong: A problem occurred configuring project ':app'.
Failed to notify project evaluation listener.
> java.lang.IllegalStateException: Cannot change attributes of configuration 'appreleaseUnitTestCompileClasspath' after it has been locked for mutation > KotlinJvmAndroidCompilation with name 'releaseUnitTest' not found. this question ?
v
That is neither a question, nor from me. That is an error message from you
u
yes. my question is I want to reslove the error
v
I asked you some questions that you ignored up to now
How do you expect to get help when you do not answer what people trying to help you ask you?
u
use-case of that code: I write a gradle plugin which can find the so file using by apk
v
That's not the use-case but the implementation. What is the use-case? What do you want to achieve? Why do you need to find the file? Just to print its name? Why does that have to be done at configuration time?
u
I just write the plugin to learn how to write gradle plugin
v
Ok. So. A
Configuration
is an
Iterable<File>
. When you call
forEach
on it, you resolve the configuration as it is configured at that point in time and iterate over the files. This means you miss any changes done after that, or if you are "lucky" the build fails if changes are attempted after that. So you should usually not do this at configuration time, but for example in the execution phase of some task.
Whenever you tend to use
afterEvaluate
, then in 98.7% of the cases it is the wrong thing to do
u
you suggestion that soSearch run at a task ?
v
You still did not explain the use-case / answer my questions, so I have no concrete suggestion. But that could be an option, yes.
u
I think I make clear
👎 1
afterEvaluate can reslove the error. afterEvaluate received atfer all configure done
👎 1
v
Let me repeat it again > afterEvaluate can reslove the error. No, it cannot. It can hide it and shift it to a later point in time.
afterEvaluate
is pratically never a fix and almost never appropriate. > afterEvaluate received atfer all configure done No, it does not. If I apply your plugin and then do something in an
afterEvaluate
or apply another plugin that also uses
afterEvaluate
that will run after your
afterEvaluate
as they are run in registration order and they are still part of the configuration phase.
As I said multiple times already, it mainly introduces timing problems, ordering problems, and race conditions, making your code flaky at best.
u
I will using task
👌 1