Hi,
This is somewhat related to @luke_daley’s reply here
We’ve written some functionality with the tooling api that we now need to evolve with a backward-compatible API change to the custom model. We’re wondering if we’re totally missing something or we aren’t following the correct pattern for this.
Our first iteration contains a model like:
// Version 1.0
interface MyModel
{
public String method()
}
There is a corresponding builder that is registered when the plugin is applied.
We want to add a method to the model to expose more information about the build to the tooling api.
// Version 1.1
interface MyModel
{
public String method()
public String newMethod()
}
We’re currently adding functionality to the existing builder to define the result of newMethod().
What’s the correct way to evolve our main class that is using the model?
public static void main( String[] args )
{
GradleConnector connector = GradleConnector.newConnector()
ProjectConnection connection = connector.connect()
final MyModel model = connection.getModel( MyModel.class )
String strMethod = model.method()
// Do something with strMethod
// Make intelligent decision if model.newMethod() exists
if( ... )
{
String strNewMethod = model.newMethod()
}
}
There will be instances where a new invocation of the tooling api will need to be backwards-compatible with Version 1.0 of the model.
The thought was that groovy could provide some information if the newMethod exists but the model returned by connection.getModel() refers to the updated model. It’s clear that since model is a Proxy object none of these options can help:
MyModel.metaClass.respondsTo( model, "newMethod" )
model.metaClass.respondsTo( model, "newMethod" )
model.metaClass.getMetaMethod( "newMethod" )
It’s only when model.newMethod() is invoked that the break to the interface causes the exception:
Exception in thread “main” org.gradle.tooling.model.UnsupportedMethodException: Unsupported method: MyModel.newMethod().
We can see a few options that address the issue:
- we should have exposed a “version” attribute/method in our initial model. Break the functionality and roll out the correct implementation with a version included with the model so future improvements can be compatible.
- catch the exception and take action appropriately?
- we’ve completely missing something that can help keep this backwards compatible.
Any ideas or thoughts are greatly appreciated. Thanks,
Nick