doWithSpring in Grails 3 plugin as a subproject - grails

I have a project built with Gradle with 3 subprojects: trawler, adaptrice, frontage. Trawler is Groovy/Java, adaptrice is a Grails 3.1.7 app, frontage is a Grails 3 plugin used by adaptrice.
The top settings.gradle says include 'trawler', 'adaptrice', 'frontage', adaptrice/build.gradle contains,
grails {
plugins {
compile project(':frontage')
}
}
All this as per the Grails documentation. Everything works -- almost. The doWithSpring method in the plugin descriptor (class FrontageGrailsPlugin) looks like this,
Closure doWithSpring() { {->
entityPropGrabberFactory(EntityPropGrabberFactory) {
constraintsEvaluator = ref(ConstraintsEvaluator.BEAN_NAME)
proxyHandler = ref('proxyHandler')
}
}}
It is never executed when I do run-app for the adaptrice Grails app. There is a NPE when a supposedly injected bean is used. If I move the body of doWithSpring to the .../spring/resources.groovy of the adaptrice Grails app then it really works.
So my question is, what causes the doWithSpring in a Grails 3 plugin descriptor to be executed? Do I have to do something special when the plugin also is a subproject?

Related

Grails 3 + Springboot dependencies

I have a Grails 3 application that depends on dependencies that are managed by springboot. How to bootstrap those springboot dependend dependencies from Grails so i can use the services and beans from the dependensies.
Extending the Application.groovy packageNames funktion by the packages used in the dependencies seem to bootstrap most of it but not all....
this should do the trick:
class Application extends GrailsAutoConfiguration {
#Override
boolean limitScanningToApplication() {
false
}
}
The dependency that manages the MongoDB Connection is working fine if started standalone, but is not generating the MongoRepositories if used inside a grails application. It seems grails enables jpareporitories, but not MongoReporitories. I simply hat do add #EnableMongoRepositories to my MongoDB configuration and now both types of repositories are generated.
Summed up I had to use
class Application extends GrailsAutoConfiguration {
#Override
boolean limitScanningToApplication() {
false
}
}
to enable scanning as mentioned above and
#EnableMongoRepositories
to enable MongoRepositoryGeneration inside of a grails app

Register custom constraints

I'm trying to upgrade Grails 2.3.7 project to Grails 3.2.3. In 2.3.7, I used custom constraints and register them in /conf/Config.groovy using:
org.codehaus.groovy.grails.validation.ConstrainedProperty.registerNewConstraint('description', my.validation.DescriptionConstraint)
Then I can use something like this in domain:
static constraints = {
approvedDate(description: '>= applyDate')
}
However, in Grails 3.2.3, When I put above command (and remove org.codehaus.groovy from package name) in /conf/application.groovy I got following error:
Error occurred running Grails CLI: No signature of method: groovy.util.ConfigObject.registerNewConstraint() is applicable for argument types: (groovy.util.ConfigObject, groovy.util.ConfigObject) values: [[:], [DESCRIPTION_CONSTRAINT:[:]]]
I've notice that validation class is somewhat changed in Grails 3. However using constraint class from Grails-validation still got the same error.
All validation plugins I found were long abandoned before Grails 3. And I can't find any document for register new constraint in Grails 3.2.
Calling ConstrainedProperty.registerNewConstraint in /grails-app/init/BootStrap.groovy works. (tested with Grails 3.2.4)
class BootStrap {
def init = { servletContext ->
grails.validation.ConstrainedProperty.registerNewConstraint('description', my.validation.DescriptionConstraint)
// The rest of bootstrap code
}
}
Note. Previously, I call it from main() in /grails-app/init/Application.groovy. It works for running application. However, it does not work with integration test.
Another way you can create the runtime.groovy under config and register your constraints in the runtime.groovy as in grails 2.x.x:
org.codehaus.groovy.grails.validation.ConstrainedProperty.registerNewConstraint('description', my.validation.DescriptionConstraint)

Grails access variable in build.gradle from Service class

I am sitting in front of a Grails 3.1.4 Application. The build.gradle file looks like this:
buildscript {
...
}
version "01.01.12.99"
...
ext {
...
}
repositories {
...
}
dependencyManagement {
...
}
dependencies {
...
}
From one of my Service Classes I want to access the version variable. Is this somehow built in into Grails or am I trying to do something impossible? Are there ways to load this variable from a Service class?
I searched a bit and found this, but it accesses the Grails version not the project version.
Well, I recently started using Grails 3. Here I got the solution:
println System.properties.getProperty("info.app.version")
And you will get "01.01.12.99". This is working on Grails 3.1.8 for me.
Another way to achieve this (in addition to the solution provided by Shashank Agrawal) is relying on grailsApplication bean, with the following code:
grailsApplication.config.getProperty('info.app.version')
I tested this with Grails 3.1.9 and 3.2.7.

How to install and use httpbuilder plugin in grails

How to install and use httpbuilder plugin in Grails?
Adding httpbuilder 0.5.1 to your application dependencies will cause errors. In particular, you'll get an error something like this:
java.lang.LinkageError: loader constraint violation: when resolving overridden method "org.apache.xerces.jaxp.SAXParserImpl.getParser()Lorg/xml/sax/Parser;" the class loader (instance of org/codehaus/groovy/grails/cli/support/GrailsRootLoader) of the current class, org/apache/xerces/jaxp/SAXParserImpl, and its superclass loader (instance of <bootloader>), have different Class objects for the type org/xml/sax/Parser used in the signature
I think the issue is that httpbuilder is exporting it's compile-time dependencies as runtime dependencies. An easy workaround is to declare the dependency like this in your BuildConfig.groovy:
grails.project.dependency.resolution = {
...
dependencies {
runtime('org.codehaus.groovy.modules.http-builder:http-builder:0.5.1') {
excludes 'xalan'
excludes 'xml-apis'
excludes 'groovy'
}
}
}
I think you need mavenRepo "http://repository.codehaus.org" in the repositories section as well.
There is the REST Client plugin:
Installation:
grails install-plugin rest
Example:
withHttp(uri: "http://www.google.com") {
def html = get(path : '/search', query : [q:'Groovy'])
assert html.HEAD.size() == 1
assert html.BODY.size() == 1
}
I ended up using the above step by ataylor but then commented out the block and tested plugin:
compile ":rest:0.7"
Rest plugin uses http-builder and without having the above dependancy my app still works fine and makes calls through http builder.

Grails behavior difference between run-app and run-war

I'm relatively new to Groovy and Grails and am trying them out in my spare time. I've got a small test Grails application that I'm able to run fine using grails run-app, but grails run-war results in an error.
In the grails-app/conf/BootStrip.init method, I'm adding some property getters onto the DefaultGrailsControllerClass and DefaultGrailsApplication:
DefaultGrailsControllerClass.metaClass.getMenuText = { ->
getPropertyOrStaticPropertyOrFieldValue('menuText', String.class)
}
DefaultGrailsControllerClass.metaClass.getMenuOrder = { ->
getPropertyOrStaticPropertyOrFieldValue('menuOrder', Integer.class)
}
DefaultGrailsApplication.metaClass.getMenuControllerClasses = { ->
controllerClasses.findAll { it.menuText != null }.sort { it.menuOrder }
}
In my grails-app/views/layouts/main.gsp, I'm using this:
<g:each var="c" in="${ grailsApplication.menuControllerClasses }">
<li><g:link controller="${c.logicalPropertyName}">${c.menuText}</g:link></li>
</g:each>
This works fine under run-app, but running it under run-war, I get the following:
groovy.lang.MissingPropertyException: No such property: menuControllerClasses for class: org.codehaus.groovy.grails.commons.DefaultGrailsApplication
I've tried this under Grails 1.1.1 and 1.2-M1 and get the same result. I've verified that the BootStrap.init method is being called (via a println), but the changes made to the metaClass don't appear to take under run-war.
Any idea what I'm missing?
grails run-war -- Run's a Grails application's WAR in Jetty
grails run-app -- Runs a Grails application in Jetty
The difference seems to be that run-war does not support reloading as run-app does.
Not sure what you are missing.

Resources