Extensions do not appear as IConventionAware


(Justin Ryan) #1

Before 1.8, I leveraged the fact that my project.extensions were IConventionAware:

ProjectPackagingExtension extension = project.extensions.create(taskBaseName, ProjectPackagingExtension, project)
        ConventionMapping mapping = ((IConventionAware) extension).getConventionMapping()

I understand that ConventionMapping isn’t a public feature, but it definitely a widely used and stable feature of Gradle. Is there some magic annotation or some marker interface to have the project.extensions.create call to the add the IConventionMapping interface? I can see that it’s still _Decorated and hence being byte-code altered, I just understand why it’s no longer IConventionAware.


#2

This is not something that was intentionally changed, and a simple sample show that regular extensions still implement IConventionAware in Gradle 1.8:

import org.gradle.api.internal.IConventionAware
def myext = project.extensions.create('myext', MyExtension)
  task out << {
 println project.myext in IConventionAware
}
  class MyExtension {}

That doesn’t explain what’s happening in your case, however. Can you provide a test case that demonstrates the problem?


(Justin Ryan) #3

Thank you for providing such a stark example. I took your example an made it closer to what I’m using:

import org.gradle.api.internal.IConventionAware
import org.gradle.api.internal.file.copy.DefaultCopySpec
  def myext = project.extensions.create('myext', MyExtension)
task out << {
    println project.myext in IConventionAware
}
  class MyExtension extends DefaultCopySpec {
    MyExtension() {
        super( null , null )
    }
}

Essentially I just learned the lesson of @NonExtensible. Since I was extending a @NonExtensible, my extension doesn’t get Convention Mapping magic. The change in 1.8 is that the previous equivalent class CopySpecImpl did not have this annotation. Thanks for your help.