Using external lib/gradle dependency lib of domain class as GORM class for a Grails 3 application

54 views
Skip to first unread message

Milan Dalsaniya

unread,
Jul 9, 2019, 3:00:11 AM7/9/19
to Grails Dev Discuss

I have been trying to create a lib of domain class(which uses GORM dependancy, Gradle build) which can be included as a dependency to my Grails Applications, as they are common domain classes used across three grails applications.


The goal is to have a common set of domain class rather than copying domain classes across the application.

But when I use this into my other Grails application, it creates a table into the database from that domain class but field are not created.

To achieve this goal, I have created a Gradle/Groovy application, created POJO classes in my src/main/groovy/abc/xyz Annotated with

grails.gorm.annotation.Entity

I build the application, publish it into my local m2 repo, and then use it as a dependency in my other grails application.

This will then create a table into my DB but it failed to create columns. I tried annotated fields with

javax.persistence.Column

but this is not working as well.

import grails.gorm.annotation.Entity
import org.grails.datastore.gorm.GormEntity

@Entity
class People implements GormEntity<People> {

    @javax.persistence.Column public String firstName
    @javax.persistence.Column public String lastName

    static constraints = {
        firstName blank:false
        lastName blank:false
    }
}

when tried to create an instance this class and save it to DB from other grails application, I got the following error.

Either class [adcomm.dom.People] is not a domain class or GORM has not been initialized correctly or has already been shut down. If you are unit testing your entities using the mocking APIs. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ExceptionInInitializerError: null
    at adcomm.ad.api.RestService.$tt__rssFeed(RestService.groovy:19)
    at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
    at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
    at adcomm.ad.api.RestController.index(RestController.groovy:14)
    ... 3 common frames omitted
Caused by: java.lang.IllegalStateException: Either class [adcomm.dom.People] is not a domain class or GORM has not been initialized correctly or has already been shutdown. If you are unit testing your entities using the mocking APIs
    ... 7 common frames omitted


What am I doing wrong here, is there a better approach or solution for this. Please help/advice.


Thank you Milan


Daniel Leahy

unread,
Jul 9, 2019, 5:04:00 AM7/9/19
to grails-de...@googlegroups.com
Hi Milan, 
              I have done what you want using Grails plugins, it seems to be the correct way to do what you want in Grails 

I am assuming your using Grails3, it would be similar in Grails2 but you wouldn't use Gradle, its a lot messier in Grails2

Create a plugin that stores the domain classes you want to share between your different classes.

grails create-plugin shareddomainclasses

cd shareddomainclasses

grails create-domain-class MyDomainClass

add your fields to the domain class you just created


Create them in the standard domain class directory in the plugin, no need for any extra annotations like GormEntity or @javax.persistence.Column

You then use the plugin using Gradle build.gradle in your different applications.

There are a number of different ways you can do that, 
  • you can publish your plugin to an artefact repository (JFrog/BinTray) lots of options, can you can even create your own, and reference that repository/plugin in your build.gradle
  • you can compile your plugin, the output is a jar file (in grails 3) in the build/libs directory, you can then copy that jar in your app and reference that jar in your application build.gradle (grails has no special directory for jars so you need to create one, libs for example and reference that directory/jar in your build.gradle)
  • you can have your plugin code in a directory on your machine that you can reference in the build.gradle of your different applications (this is what I personally do, so I can edit the domain classes at will and run the apps to pick up the domain classes changes). I can do this because I am not sharing the plugin code with anybody else and i have complete control over the apps created
Regards,
                Daniel Leahy.








--
You received this message because you are subscribed to the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.
To post to this group, send email to grails-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grails-dev-discuss/196486c1-4a10-4948-a1c3-45cd716f73cc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

justde...@gmail.com

unread,
Sep 4, 2020, 12:36:26 AM9/4/20
to Grails Dev Discuss
Hi Daniel,

I know it's very long time to respond to your suggestions. So Thank you very much for that.

I did follow your suggestion and create a grails3 plugin will all the common domain classes.
If i do "install", it will publish plugin to my local .m2 cache and it work well.

But if I do "maven-publish" to our org's jfrog artifactory and try to use it as dependency, it does not resolve from artifactory (plugin did get publish to jfrog maven artifactory).

So how can I publish my plugin into jfrog artifactory(maven repo) of my org so that my application can resolve dependency?

Please advice.

Thank you

Milan
Reply all
Reply to author
Forward
0 new messages