smbergin79
smbergin79

Reputation: 1271

Coercion befuddlement in Groovy

Why does the following

class Test {
  @Test
  void go() {
    def foo1 = new MockFoo1() as Foo
    def foo2 = new MockFoo2() as Foo
  }

  interface Foo {}

  class MockFoo1 {}

  class MockFoo2 {}
}

Result in a java.lang.IllegalArgumentException: argument type mismatch on the foo2 coercion?

This only happens if I coerce 2 objects of 2 different types to the same interface during a single path of execution. The groovy approved way of using closures or maps to achieve this kind of duck typing works fine.

Any light shed appreciated.

Upvotes: 0

Views: 175

Answers (1)

Daniel Woods
Daniel Woods

Reputation: 1029

It's a bug with the ProxyGenerator adapterCache. As a workaround, you can also use some Groovy trickery to make this work:

interface Foo {
    static a = {
        [MockFoo1, MockFoo2].each {
            it.metaClass.asType = { Class klazz ->
                try {
                    DefaultGroovyMethods.asType(delegate, klazz)
                } catch (e) {
                    def cache = ProxyGenerator.INSTANCE.@adapterCache.@cache
                    cache.each { k, v ->
                        cache.remove(k)
                    }
                    DefaultGroovyMethods.asType(delegate, klazz)
                }
            }
        }
    }()
}

class MockFoo1 {}
class MockFoo2 {}

def a = new MockFoo1() as Foo
def b = new MockFoo2() as Foo

assert a instanceof Foo
assert b instanceof Foo

Hope this helps!

Upvotes: 1

Related Questions