Register custom constraints - grails

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)

Related

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 we can use A template profiler plugin in grails 2.4.3

Forgive me for my English. Actually I want to use A template profiler plugin in grails 2.4.3. But it is unable to install in this grails version. It is available for the grails version 1.3.2. And I want to use it for grails 2.4.3. When I am trying to install. It shows an error
| Error Compilation error: startup failed:
C:\Project\target\work\plugins\profile-template-0.1\grails-app\services\profile\te
mplate\ProfileTemplateService.groovy: 5: unable to resolve class
org.codehaus.groovy.grails.commons.Configurat ionHolder # line 5,
column 1. import
org.codehaus.groovy.grails.commons.ConfigurationHolder ^
C:\Projects\target\work\plugins\profile-template-0.1\grails-app\services\profile\te
mplate\ProfileTemplateService.groovy: 8: unable to resolve class
org.codehaus.groovy.grails.commons.Configurat ionHolder # line 8,
column 26.
boolean isRecording = !(ConfigurationHolder.config?.profile?.template?.disabled as Boolean)
^
2 errors
Can anybody help me to get me out of this. Or You can suggest me another alternate option for this.
Thanks in advance.
If you have access to the source code of the plugin you could follow this:
In Grails 2 we no longer use ConfigurationHolder we use GrailsApplication.getConfig() instead. In the ProfileTemplateService add field GrailsApplication grailsApplication (Spring will inject it during app boot up) and change the:
ConfigurationHolder.config?.profile....
to
grailsApplication.config.profile...
Your service class should look like:
class ProfileTemplateService {
GrailsApplication grailsApplication
def method() {
a = grailsApplication.config.profile
}
}
Obviously there can more hoops to jump through before you actually make the plugin work.

Grails 3.0.1 and Hibernate Session error

I am following a book example (Grails in Action 2nd edition) which is based on Grails 2.* but I am using the new Grails 3.0.1.
When I create a domain class that looks like:
package qotd
class Quote {
String content
String author
Date created = new Date()
}
I get an Exception thrown whenever I try to interact with the DB through the groovy console.
org.springframework.dao.DataAccessResourceFailureException: Could not obtain current Hibernate Session;
Caused by: org.hibernate.HibernateException: No Session found for current thread
I have tried to add #Transactional to the domain class and also swith to a lower JDK version(7) but none of them works.
I have also tested with Grails 3.0 and results are same.
If I downgrade to Grails 2.5.0 it works so it is a Grails 3.* issue. Gradle could be the issue.
I wrapped everything inside a transaction for Grails 3
qotd.Quote.withTransaction {
new qotd.Quote(author: 'Larry Wall',
content: 'There is more than one method to our madness.').save()
}

Repetitive method name/signature for method compilation error when using #I18nFields

I get repetitive method name/Signature compilation failure when i try to use i18nFields in my domain class to support multiple languages.
Grails Version : 2.3.7 ( I tried with 2.3.4 and got the same issue and upgraded)
Documentation from Grails followed for this was http://grails.org/plugin/i18n-fields
My Domain class looks like
package com.sampleapp.domain
import i18nfields.I18nFields;
#I18nFields
class Products {
def name
static constraints = {}
static i18nFields = ['name']
}
My Config.groovy has the below line included to specify the locale
// internationalization support - testing
i18nFields {
locales = ['en','es']
}
BuildConfig.groovy plugin definition
plugins {
// plugins for the build system only
build ":tomcat:7.0.47"
// plugins for the compile step
compile ":scaffolding:2.0.1"
compile ':cache:1.1.1'
// plugins needed at runtime but not for compilation
runtime ":hibernate:3.6.10.6" // or":hibernate4:4.1.11"//
runtime ":database-migration:1.3.8"
runtime ":jquery:1.10.2.2"
// compile ":jquery-ui:1.10.2.2"
runtime ":resources:1.2.1"
// Uncomment these (or add new ones) to enable additional resources capabilities
runtime ":zipped-resources:1.0.1"
runtime ":cached-resources:1.1"
//runtime ":yui-minify-resources:0.1.5"
compile ':platform-core:1.0.RC6'
compile ":cache-headers:1.1.5"
runtime ':spring-security-core:2.0-RC2'
// internationalization
compile ":i18n-fields:0.8.1"
}
The compilation error is
grails-workspace\Test\grails-app\domain\com\sampleapp\domain\Products.groovy: -1: Repetitive method name/signature for method 'void setName_es(java.lang.String)' in class 'com.sampleapp.domain.Products'.
# line -1, column -1.
The Error is repeated for the name property for both en and es locales twice.
There is no error if i remove the i18nFields annotation and the sample app worked fine before this. I verified GGTS repetitive method name/signature error in controllers post for similar error in controller. I have also verified to ensure that groovy version is correct and in my case it is 2.1
Can somebody please give me any pointers on where i should look to resolve this issue.
This problem shows up when you are trying to use Java > v7 with any version of Grails < 2.3.7. Either downgrade your jvm or upgrade your grails.
Thanks for trying (and for making me know via github ;) )
The issue was known but hadn't been tackled yet.
The previous answer (commenting out methods) is not exact, event though it follows the right track, because the problem comes from new changes in Grails that will cause a collision in getters and setters.
The solution I've found is to separately create the property and the getter/setter, and it seems to work.
I'm releasing a new version as soon as it can be fully tested in a project, but code is already available in https://github.com/jorgeuriarte/grails-i18n-fields-plugin/tree/redis_integration (version 0.9-redis-SNAPSHOT) in case you want to use it.
Probably it has something to do with the new Binding mechanism in grails 2.3. Maybe the getters and setters are set automatic now?
When I comment out these two lines in ClassI18nalizator.groovy the error disappears. It seems to work at least partly. I can use the fields in scaffolding. It's not a real solution but maybe a hint for someone who understands grails better than me.
private def getSetterMethod(field) {
// setter should return void. that's why the return statement.
//return new AstBuilder().buildFromString("i18nfields.I18nFieldsHelper.setValue(this, '${field}', value); return;").pop();
}
private def getGetterMethod(field) {
//new AstBuilder().buildFromString("i18nfields.I18nFieldsHelper.getValueOrDefault(this, '${field[0..-7]}', '${field[-5..-1]}')").pop();
}
After that I run into a second issue:
No signature of method: groovy.util.ConfigObject.contain() is
applicable for argument types: (java.lang.String) values: [en_US]
I solved it by adding redisLocale to Config.groovy
i18nFields {
locales = ['de_DE', 'en_US']
defaultLocale = "en_US"
redisLocales = ['de_DE', 'en_US']
}

Grails 2.2 not recognizing homepage view

I'm upgrading a grails 1.3.6 app to 2.2.4. In 1.3.6, the app is accessed by hitting localhost:8080/APPNAME. This then renders the file in grails-app/views/index.gsp.
After upgrading the app to 2.2.4, hitting localhost:8080/APPNAME' returns an error of :
HTTP Status 404 - "/index.gsp" not found..
My URLMappings file is as follows:
class UrlMappings
{
static mappings =
{
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
//"500"(view:'/error')
"500"(controller: 'pacErrors', action: 'handleErrors')
}
}
I am able to access controllers directly via URL calls, so the server does appear to be up and running.
It all seems correct, sometimes when confronted with weird behaviours after an upgrade, I find the best fix is a "grails clean", and make sure that the app is indeed migrated to 2.2.4 by running "grails upgrade".
If this does not work, try creating a new application directly with grails 2.2.4 to test it out. If you cannot spot the problem after that, you could copy your existing app into the new one.

Resources