Main issue: It seems that if I modify a Java class's metaClass then such changes are only honored if my Groovy code is invoking that Java class. However if another Java class is invoking the Java class that I modified, then the metaClass changes are ignored.
I guess this behavior seems to be proper (the Java code that was compiled will not check the Groovy meta-class registry) but I was hoping someone can give me some other ideas on how to achieve my goals. Here's some sample code:
A.java:
public class A {
A() {
System.out.println("A constructor");
B b = new B();
b.foo();
}
}
B.java:
public class B {
B() { System.out.println("B constructor"); }
public void foo() { System.out.println("B.foo() invoked"); }
}
Compilation:
javac *.java
jar cvfe java.jar Main *.class
foo.groovy:
println 'Groovy now invoking Java...'
new A()
println 'Modifying B.metaClass'
B.metaClass.foo = { -> println 'modified foo() method!' }
println 'Groovy now invoking Java...'
new A() // <<===== I would like to see the "modified foo()" here but I don't :(
println 'Groovy creating B directly'
new B().foo() // "modified foo()" appears here
Run:
> groovy -cp .:java.jar foo.groovy
I have a Grails app that uses some existing Java JARs (bytecode, no access to its source code). I'd like to intercept some calls to certain methods in these Java classes, but those methods are invoked by other Java classes in that same JAR.
Spring AOP is out of the question because the objects in question are not managed by Spring.
Bigger picture: I'm actually trying to solve the problem I stated in:
My idea was to write code like the following:
import org.codehaus.groovy.grails.orm.hibernate.validation.UniqueConstraint
class HibernateEnhancerGrailsPlugin {
def loadBefore = ['hibernate']
def doWithSpring = {
UniqueConstraint.metaClass.processValidate = { final Object target, final Object propertyValue, Errors errors ->
// no-op...
}
}
}
Thoughts?