Spring Security Plugin Issue in Grails 2.4.4 - grails

I'm following this tutorial for Spring Security Authentication:
http://spring.io/blog/2010/08/11/simplified-spring-security-with-grails/
Video: https://www.youtube.com/watch?v=auwML_bsUEE
I can't follow the step in 4:50.
package org.example
import grails.plugins.springsecurity.Secured
class PostController {
...
#Secured(['ROLE_USER'])
def followAjax = { ... }
#Secured(['ROLE_USER', 'IS_AUTHENTICATED_FULLY'])
def addPostAjax = { ... }
def global = { ... }
#Secured(['ROLE_USER'])
def timeline = { ... }
#Secured(['IS_AUTHENTICATED_REMEMBERED'])
def personal = { ... }
}
import grails.plugins.springsecurity.Secured is not found.
I'm using Grails 2.4.4 and compile ':spring-security-core:2.0-RC4' in BuildConfig.groovy. Thanks.

That tutorial is more than 4 years old, a lot has changed since then. Try reading the plugin docs - I'm sure that there are several other changes like this that will cause issues.
The import should be grails.plugin.springsecurity.Secured. You can also use the Spring Security org.springframework.security.access.annotation.Secured annotation, but the plugin's annotation supports all of the same features and a few additional ones, e.g. letting you define the rules with a Closure.
You can't use either annotation on an action defined as a Closure though. They are still supported in Grails 2.0+ but methods are now preferred, and although Grails lets you define actions with closures or actions, the plugin only supports methods.

Related

NullPointerException when calling service methode in a domain class methode

According to Grails it should be possible to use a service within a domain class. But when I run the following simple example, the grails run-app fails with a NullPointerException: "Cannot invoke method test() on null object"
To reproduce use the following code pieces:
Bootstrap.groovy:
class BootStrap {
def init = { servletContext ->
new Test().test()
}
def destroy = {
}
}
with the service:
#Transactional
class TestService {
def test() {
}
}
and the domain class:
class Test {
def testService
def test() {
testService.test()
}
}
This happens with Grails 3.2.9 and 3.3.0. Is this a Grails error or a GORM failure, not auto injecting the service into domain classes ?
SOLUTION:
For all wondering what the solution is (see answer from erichelgeson) using "static mapping = { autowire true }". But testing both solutions, I found that "static mapping ..." works in Grails 3.3.0 and in 3.2.9, hence setting it globally in application.yml did only work for Grails 3.2.9 but not in Grails 3.3.0 thou.
Recent versions of Grails (3.2.9+) have disabled autowire by default on domain classes for performance reasons. You can re-enable it:
per domain:
static mapping = {
autowire true
}
or globally in application.yml/groovy
grails.gorm.autowire = true
See more # http://gorm.grails.org/6.1.x/hibernate/manual/index.html
Section 1.2.9
You could reenable autowiring per the previous suggestion, but there are performance implications to your whole application for that. It may be worth it, if this is a common situation.
If this is a rare situation for you, you can also access a service as so, in a domain class:
Holders.applicationContext.serviceName.methodName()

How to use Flyway in a Grails 3 project with Spring Boot's autoconfig

According to the Flyway documentation it should be possible to use Flyway in a Grails 3 project out-of-the-box:
Grails 3.x is based on Spring Boot comes with out-of-the-box integration for Flyway.
All you need to do is add flyway-core to your build.gradle:
compile "org.flywaydb:flyway-core:4.1.1"
Spring Boot will then automatically autowire Flyway with its DataSource and invoke it on startup.
This doesn't work for me. Flyway does not kick in at application startup. In the logs I see some suspicious lines:
FlywayAutoConfiguration did not match
- #ConditionalOnClass found required class 'org.flywaydb.core.Flyway' (OnClassCondition)
- #ConditionalOnProperty (flyway.enabled) matched (OnPropertyCondition)
- #ConditionalOnBean (types: javax.sql.DataSource; SearchStrategy: all) did not find any beans (OnBeanCondition)
...
Exclusions:
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
And this is how Spring's FlywayAutoConfiguration class looks like:
#Configuration
#ConditionalOnClass(Flyway.class)
#ConditionalOnBean(DataSource.class)
#ConditionalOnProperty(prefix = "flyway", name = "enabled", matchIfMissing = true)
#AutoConfigureAfter({ DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
public class FlywayAutoConfiguration {
So it looks to me that it is not working because DataSourceAutoConfiguration is excluded from auto-config.
Is this analysis correct?
Why and where is DataSourceAutoConfiguration excluded? Supposedly somewhere deep inside of Grails, because I am not aware of any place in my code that could cause this.
How can I make the flyway integration into Grails work as promised by the Flyway docs? I know I can do it manually via resources.groovy (working code from my project, heavily inspired by Grails Flyway plugin code):
if (application.config.flyway.enabled != false) {
flyway(Flyway) { bean ->
bean.initMethod = 'migrate'
dataSource = ref('dataSource')
baselineOnMigrate = application.config.flyway.baselineOnMigrate
}
BeanDefinition sessionFactoryBeanDef = getBeanDefinition('sessionFactory')
if (sessionFactoryBeanDef) {
def dependsOnList = ['flyway'] as Set
if (sessionFactoryBeanDef.dependsOn?.length > 0) {
dependsOnList.addAll(sessionFactoryBeanDef.dependsOn)
}
sessionFactoryBeanDef.dependsOn = dependsOnList as String[]
}
}
but if possible I'd prefer the auto-config approach because it supports many flyway properties out-of-the-box and I can keep my resources.groovy tidy.

Using Groovy Library in Grails and getting 'No suitable ClassLoader found for grab'

I'm playing around with Grails/Groovy and have some straight Groovy code working that utilizes groovy-wslite. That code starts as such
send-request.groovy
#Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.0')
import wslite.soap.*
When I implement that into my Grails code and view the controller/action I get this
Error 500: Internal Server Error
URI: /FormProj/hello/trigger
Class: java.lang.RuntimeException
Message: No suitable ClassLoader found for grab
And here's the code in it's current state (I've tried a LOT of different things)
HelloController.groovy
package com.demo
import groovy.grape.Grape
class HelloController {
def index() { }
def sayHi() {
return [
greeting : "Hi there, ${ params.name }"
]
}
def trigger() {
Grape.grab(group:'com.github.groovy-wslite', module:'groovy-wslite', version:'1.1.0')
…
}
}
As I'm sure you notice I'm very green with Grails/Groovy and really all things Java. I do know there is a wslite plugin for Grails, but surely this can work too right?
Grails: 2.3.8
Groovy: 2.2.2
UPDATE
Based on Ian Robert's advice I have updated my BuildConfig file by adding this line to the dependencies block
compile 'com.github.groovy-wslite:groovy-wslite:1.1.0'
And updated my controller to look like this
HelloController.groovy
package ws.thejspot
import wslite.soap.*
class HelloController {
def index() { }
def sayHi() {
return [
greeting : "Hi there, ${ params.name }"
]
}
def trigger() {
def client = new SOAPClient('URL')
}
}
Unfortunately now the IDE, GGTS, shows an error in the controller 'unable to resolve class SOAPClient'
Rather than trying to download the dependencies with #Grab, you should use the standard Grails dependency mechanism - edit grails-app/conf/BuildConfig.groovy and look for the grails.project.dependency.resolution closure. Inside that, in the dependencies block you should add
compile 'com.github.groovy-wslite:groovy-wslite:1.1.0'
and remove anything Grape-related from the controller, leaving just the import wslite.soap.*
You will probably need to run
grails compile --refresh-dependencies
at least once to ensure that Grails picks up your change to BuildConfig - it deliberately doesn't do a full dependency resolve every time you compile, so as not to slow down the build too much, so you need to tell it to refresh when you know it needs to.

Grails 2.4 Command objects nullable constraint and dependency injection

we are preparing for Grails 2.4 upgrade. One of the issues we face is that
most of the command object unit tests fails because of injected properties, like
services, are required to be not null during validation.
Is there any suggested way how to test this? Should we mock all properties although some are not needed for test? or is there a way to do this differently?
After my question is answered by Jeff, I share links with more information about new functionalities:
doWithSpring and doWithConfig are shortly described in What's new in 2.4: http://grails.org/doc/latest/guide/introduction.html#whatsNew24 in Unit Testing improvements section
There is also a JIRA issue with example: https://jira.grails.org/browse/GRAILS-11003
Most unit tests don't want or need the application context all spun up and populated. Unit tests can add whatever they want (or nothing) to the application context. In recent versions of Grails you can do something like this...
A controller and command object:
// grails-app/controllers/demo/DemoController.groovy
package demo
class DemoController {
def processName(SomeCommand co) {
render co.someValue
}
}
class SomeCommand {
String name
def helperService
def getSomeValue() {
helperService.processValue(name)
}
}
A service:
// grails-app/services/demo/HelperService
package demo
class HelperService {
def processValue(String originalValue) {
"__${originalValue}__"
}
}
A unit test:
// grails-app/test/unit/demo/DemoControllerSpec.groovy
package demo
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(DemoController)
class DemoControllerSpec extends Specification {
def doWithSpring = {
helperService HelperService
}
void 'process name'() {
when:
params.name = 'Jeff'
controller.processName()
then:
response.contentAsString == '__Jeff__'
}
}
That test will pass with Grails 2.4.2.
I hope that helps.

Exposing a configuration property via getter in a quartz job

Relating to Accessing grails application config from a quartz job:
Apparently, DI doesn't happen prior to the creation of a job. I'm guessing this is the same with other grails artefacts (couldn't spot relevant documentation).
In my particular case, I was aiming to load a property from config and expose that property from the job class. In general though, it seems a valid use-case to me, that artefacts will load configuration, and then return those properties via API.
I'm wondering then, how could this be achieved when a class cannot rely on access to grailsApplication.config at construction.
Thanks
Try with:
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
class MyJob {
def execute() {
def myConfigVar = CH.flatConfig.get('my.var.setup.in.config.groovy')
...
}
}
OR
import grails.util.Holders
class MyJob {
def execute() {
def myConfigVar = Holders.config.my.var.setup.in.config.groovy
...
}
}

Resources