0
votes

Is it possible to use the classes from a grails binary plugin as a regular dependency in a groovy project?

After many different approaches the answer seems to be NO, but I feel like there is just a missing little piece dealing with dependencies.

Using:

  • sample-grails(grails 2.3.7) : Binary grails plugin with one dummy domain
  • sample-groovy(groovy 2.2.1) : Groovy project that justs prints 'Hi' and regular dependency on 'sample-grails-1.0-SNAPSHOT.jar'

Problems:

  1. If you dont add anything it does not compile:

    NoClassDefFoundError: org/grails/datastore/mapping/dirty/checking/DirtyCheckable.

  2. Add dependency "org.grails:grails-datastore-gorm-hibernate4:3.0.0.RELEASE"

    NoClassDefFoundError: Lorg/codehaus/groovy/grails/plugins/web/api/ControllersDomainBindingApi;

  3. Add dependency "org.grails:grails-plugin-controllers:2.3.7"

    Compiles ok

    In runtime crashes:

    Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/ServletResponse at org.codehaus.groovy.grails.plugins.web.api.ControllersDomainBindingApi.getDomainClass(ControllersDomainBindingApi.java:97) at org.codehaus.groovy.grails.plugins.web.api.ControllersDomainBindingApi.initialize(ControllersDomainBindingApi.java:58) at com.nortia.sample.Other.(Other.groovy) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77) at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:102) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190) at Library.main(Library.groovy:7) Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletResponse at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ... 13 more

1

1 Answers

2
votes

Creating a binary plugin is not the best approach as binary plugins really need a Grails environment. You can however create a binary plugin just using Gradle. The Cloud Foundry team do this, all you need to do is create your plugin class. Example:

https://github.com/cloudfoundry/java-buildpack-auto-reconfiguration/blob/master/auto-reconfiguration/src/main/groovy/org/cloudfoundry/reconfiguration/grails/JavaBuildpackAutoReconfigurationGrailsPlugin.groovy

And then create a META-INF/grails-plugin.xml file pointing to the class. Example:

https://github.com/cloudfoundry/java-buildpack-auto-reconfiguration/blob/master/auto-reconfiguration/src/main/resources/META-INF/grails-plugin.xml

You can then just use Gradle's standard groovy plugin to build your project.

If you want to create GORM entities then you need to add a dependency on the GORM jars. Example:

 compile "org.grails:grails-datastore-gorm-hibernate4:3.1.0.RELEASE"

Then annotate each GORM entity with grails.persistence.Entity. Example:

 import grails.persistence.*

 @Entity
 class Foo { 
    String bar 
 }

Then modify your grails-plugin.xml file to point at the entity. Example:

    <plugin name='myplugin' version='0.1' grailsVersion='2.4 &gt; *'>
      <author>Your name</author>
      <title>My Plugin</title>
      <type>foo.bar.MyGrailsPlugin</type>
      <resources>
        <resource>mybin.Foo</resource>
      </resources>
    </plugin>