I’ve got an application being build by Maven that is a mixed Groovy and Java project.
Using the GMaven plugin(v1.3), I can easily run Groovy tests against Java and Groovy classes. And during builds of the application, my java classes get linked against the augmented stub files that declare methods from GroovyObject.
However, if I write a test in Java against the application Groovy code and try to call methods from GroovyObject, I get compile time failures.
Is there any workaround for this? Is there any configuration parameters to GMaven that will make this possible?
thanks.
here’s the build.plugins stuff from my pom:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<includes>
<include>target/generated-sources/groovy-stubs/main</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<goals>
<goal>generateStubs</goal>
<goal>generateTestStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<!-- providerSelection probably defaults to 1.7 now -->
<providerSelection>1.7</providerSelection>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Here’s the java test class:
public class JavaGroovyTest extends TestCase {
@Test
public void testGroovyClasses(){
Model m = new Model(); //Model is an application class written in Groovy
assertNotNull(m);
assertEquals(4,m.getMetaClass().getProperties().size());
}
}
And here’s the compiler output:
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
/Users/mkohout/Documents/trunk/src/test/java/JavaGroovyTest.java:[17,24] cannot find symbol
symbol : method getMetaClass()
location: class com.q.Model
Declare the groovy object as a GroovyObject. Example:
Edit: a longer explanation
The groovy compiler adds a
getMetaClassmethod to classes, but it marks it assynthetic. This is an internal JVM flag for methods and fields that are generated as “implementation details” and shouldn’t be visible to code. You can verify this with javap:You can get around this though, by casting it to the
groovy.lang.GroovyObjectinterface, which declares thegetMetaClassmethod (this time not synthetic).This may not be a great solution, but that said, poking around the groovy metaClass in java is probably ill-advised in the first place. If it’s not possible to just use groovy in your tests, I’d look at exposing the metaClass information you need from the groovy classes with normal java accessible methods.