How to access domain classes from a custom plugin to another? - grails

I am currently working on grails project. I have created eight different plugins. Each having a set of Domain classes and other stuffs. Now, from one of my plugins, a certain Domain class needs to access a domain class from the other plugin. How will I do that? Do I have to import the domain classes from the other plugin? If so, how? or Shall I do that in BuildConfig.groovy?
Please help!
Thanks!

Simple make the plugin that need other plugin domains dependent from it in buildconfig
//buildConfig of plugins need other plugin domains
grails.project.dependency.plugins{
...
compile ':<other-plugin-name>:<other-plugin-version>'
...
}
The simply import the right package where you need it.
If you are constantly working on the depended plugin and you don't want to repackage it constantly you can connect it using grails.plugin.location instead of grails.project.dependency.plugins.
in buildConfig add
grails.plugin.location.'other-plugin-name' = "/path/to/other/plugin/folder"

Related

In Grails, how can I override the AuditlLogEvent domain class from Audit-Logging plugin?

I tried to create a domain subclass (different package) but migration plugin returned ambiguous class exception.
I tried creating a copy of that domain class (same package) but compiler returned duplicate class error.
How to override the AuditLogEvent class properly? Should I create a customized copy of that plugin?
We're working on a bootstrap integration of the AuditLogEvent class, so everyone got it in their project instead of the plugin integrated one. You can create it from the source branch for testing:
https://github.com/robertoschwald/grails-audit-logging-plugin/tree/feature_1.x/externalizeALE1.x
When using this 1.0.6-SNAPSHOT version in your project, you must perform "grails audit-quickstart" to create the AuditLogEvent domain class in your project. It's registered in Config.groovy. See audit-test test application setup how it works.
Would be great if you can feedback in https://github.com/robertoschwald/grails-audit-logging-plugin/issues/13

Encapsulating services in a plugin

I get the idea in Grails Services from a plugin can be injected into applications that use that plugin. But, what if don't want some services to be injectable, you only want the plugin to know about them.
Is there anyway to achieve this?
You can achieve it using pluginExcludes property in *GrailsPlugin.groovy script:
def pluginExcludes = [
"grails-app/services/com/my/package/MyService.groovy",
]
This way the service won't be included into packed plugin *.zip file.
One drawback is that this approach does not work for in-place plugins - see http://jira.grails.org/browse/GRAILS-5404
In-place plugins are the ones that are loaded from file system using the path specified:
grails.plugin.location.shiro = "/home/dilbert/dev/plugins/grails-shiro"
All Grails services are exposed as Spring beans. These beans are available through the application context, and thus the containing application that uses the plugin. There really isn't a way to 'protect' these services from being used.

Including Liferay .jars in groovy for portlet development

We are developing liferay portlets in groovy using the portlets and liferay portlets plugins. We wanted to find the user ID of the current user logged in. In order to do that, using the com.liferay.model.user class was suggested (from searching on other S.O. questions).
Unfortunately, when we try to import com.liferay.* (or com.liferay.model.user etc.) the grails complier cannot resolve the 'user' class. This makes sense, since the com.liferay folder is not in the grails/lib folder. However, I am unable to find out where to acquire these .jar files to add them to the lib folder in grails.
Am I approaching this wrong?
(Note: I am using Liferay 5.2.3, not the newest version of liferay)
Or, in 5.2.X is there an easier way to get the ID or name of the currently logged in user?
[UPDATED]
mvnrepository.com isn't a repository itself, it's a search engine for Maven artifacts.
By looking at the "Download jar hyperlink", I see that the liferay jars are available in Maven Central http://repo1.maven.org/maven2/com/liferay/portal/.
In the repositories section of your BuildConfig.groovy, make sure that the following line is there
mavenCentral()
I think the portal-impl artifact contains com.liferay.model.user.* related classes which are what you're looking for.
In that case you would have the following dependency in your BuildConfig.groovy
compile 'com.liferay.portal:portal-impl:5.2.3'
If you require additional liferay classes, assuming you have liferay running somewhere, you could search the jars for a specific class name (http://java.net/projects/jarscan). Once you know the jar name, you can search it on mvnrepository.com and add the relevant dependency to your BuildConfig.groovy.
Hope it helps.
You can reference liferay dependencies in your BuildConfig.groovy. You would need to confirm the repository URL and then it should be fine.
http://mvnrepository.com/artifact/com.liferay.portal
You could exclude those dependencies from packaging.

Common backend Grails application

I have a Grails Application AppA. And I am planning to create a new Grails Application AppB, wherein AppB practically uses the same services and models of AppA.
How should I approach that?
Extract a Grails Application AppC which would have the common services and expose that service as a remote/web/rest service?
Extract a Groovy project ModC that will be a jar containing the common services and models and have AppA & AppB depend on ModC?
Just git clone and cherry-pick every now & then?
Other suggestions?
Note that AppA have some lazy-loaded relationship invocations (i.e. entity1.entity2.entity3.propName) & GORM invocations (i.e. Entity1.get(1L)) from the presentation layer (controllers & views) as well. Although I can probably push some of them back to the services, I'm concerned about the refactoring effort to have the relationship invocations from the view remain intact (i.e. I would need to eager loaded some associations, or create Data Transfer Objects)
The Grails way to share common functionalities, utilities and whatnot is to make a plugin that encapsulates those and install it to both projects.
A plugin can contain anything you can put in a regular Grails app -- i.e. Models, Service, Views, Controllers, config files, resources under web-app etc.
You can then either release it to an internal svn repository or just use it with package-plugin
Edit:
One way to do it while you are constantly updating the code is to have it as an inline plugin. So remove the plugin from your application.properties and add:
grails.plugin.location."name-of-plugin" = "/path/to/plugin/dir" // or "../plugin/"
This removes the necessity of reinstalling the plugin all the time. But this is for development time only.
Have you considered the option of separating your models and services (the ones used by both apps) into a plugin. I think that is the prefered way at least from what I have been following within the community.
You can take a look at this link. It is not exactly equivalent to your case, but should give you a good idea for the plugin approach.
I had this situation on a previous project and we used a plugin project to hold our common functionality and it worked really well. I don't think a jar file would work well since as far as I know you wouldn't be able to take advantage of things like auto-wiring dependency injection of services, the domain/GORM/dynamic finders on domain objects, etc.
I think I would put the functionality into a separate jar and use it in the two applications (so your suggestion no 2). I wouldn't make a new application (suggestion 1) because you just need some services not a whole web application, and I wouldn't do suggestion 3 because the services wouldn't be as reusable as with suggestion 2.

Specifying order of plugins in Grails

My grails application depends on several grails plugins that append and entries to web.xml
The problem is I need to control the order the plugins are executed. There is a particular plugin which is used for some security purposes which adds a filter in web.xml. This filter needs to be the first executed filter in web.xml Thus I would like this filter to be executed last so that I can ensure that this plugin will be appending the configurations in the first position.
I know there is a dependsOn property on the plugin class to ensure it gets executed last, but that only works if I know which plugins are going to be used in combination with this plugin. I would like this plugin to be general enough so that anyone in my company can use this plugin and know for sure that this gets executed last.
Is there any way I can ensure a particular plugin gets executed last? Either in the grails-plugin project (ie a property of the plugin class) or configuration of the grails application project.
Thanks,
Does the grails application install plugins using the install-plugin command? If so, try declaring them in BuildConfig.groovy instead.
plugins {
runtime ':weceem:0.8'
runtime ':hibernate:latest.release'
}
It's possible that plugins declared here are loaded in the same order they're listed, though I haven't tested this theory.
It might be easier to find a way to make your plugin append it's filters differently to ensure they get appended to the position you want them in. I would have to see the code for the plugin if I was going to try to help solve this in that way though.

Resources