Groovy named parameter causing ClassCastException - jenkins

I have a Groovy script which is run in Jenkins. For context, I am using the SAML Plugin, and specifically using the SamlSecurityRealm constructor. This works fine.
However, to improve readability, I have attempted to used named parameters. The parameter binding, which is of type String, is causing the following exception:
java.lang.ClassCastException: java.lang.String cannot be cast to groovy.lang.Binding
My usage is like this:
binding = 'String value'
This syntax is working for all of the other parameters, and if I remove just this one named parameter, the script runs.
I am familiar with Java and Scala, but not so much with Groovy. binding does not seem to be a keyword, but I am assuming I need to escape it somehow? Wrapping it in single or double quotes, or backticks is also not working.

if you are inside groovy Script then binding = XYZ tries to call Script.setBinding(XYZ)
https://docs.groovy-lang.org/latest/html/api/groovy/lang/Script.html
unless you declare a variable binding like this:
def binding = XYZ

Related

Create custom parameter to Grails application's configuration

I am using Intellij IDEA and Grails as my application framework.
My application is mainly on Groovy.
I am trying to add external custom argument as an external parameter to my application.
I have opened the Edit Configurations... and tried different ways to add custom arguments in the VM options, and inside the Program Arguments, but with no success.
Here is an example to one try I did:
I added
-Dcustom.arg=100
to the VM options.
I would like to know if it is possible to inject external variable by using the Application configuration?If yes, how should it be done?
It should be done by adding a new program argument to the Edit configuration --> Program Arguments:
Just add a new value of the custom argument such as: externalArg.
And in the application code, find the section read those properties.
For example:
Properties props = System.properties
String propValue = props.get("sun.java.command").toString()
the propValue contains all the Program Arguments and specifically the externalArg parameter you have inserted.
Another option can be done by inserting the variable into the Edit configuration --> VM Options. When using grails, the parameter should look like that:
-Dgrails.externalVariable=3
Reading the externalVariable inside the application is done by:
Object externalVariable = System.getProperties().get("grails.externalVariable")
Note:
Both of those 2 options give the same result.
Using each one of the options should be related to the variable concept.
If you wish to have the externalVariable as a program argument insert the parameter into the Program Arguments.
If you wish to have the externalVariable as a Virtual machine parameter insert the parameter into the VM Options.

Groovy syntax, named block?

I'm starting to learn grails and there is some groovy syntax that I don't get at all, and is undocumented as far as I can tell because I don't know what it's called.
What are 'grails', 'views', and 'gsp' in the code below?
grails {
views {
gsp {
encoding = 'UTF-8'
// ...
}
}
}
Thanks!
p.s. I feel like an idiot for not being able to figure this out...
This is an example of DSL (domain specific language) code. In Groovy, many DSLs are implemented as Groovy code, although sometimes it can look pretty funky. This code block is run as Groovy code, and it's more clear that it's code if you add in the omitted optional parentheses:
grails({
views({
gsp({
encoding = 'UTF-8'
// ...
})
})
})
and more so if we replace the property set call to the equivalent method call
grails({
views({
gsp({
setEncoding('UTF-8')
// ...
})
})
})
If you ran this in a console or as part of other Groovy code or in a Grails app it would fail, because there's no 'grails' method taking a closure as an argument, or a similar 'views' or 'gsp' method, and there's no setEncoding(String) method either. But when run as DSL code, often the code is run inside a closure whose delegate is set to a DSL helper class that handles the resulting methodMissing and propertyMissing calls.
This helper looks at the method name and the number and/or types of the method arguments (or property name and value type) and if they are valid for the DSL, it does the corresponding work, otherwise it throws a MissingMethodException/MissingPropertyException, or a DSL-specific exception, or handles the problem some other way.
In this case, there's a configuration DSL handler that translates these method calls into config property calls.
There are several other DSLs in use in a Grails app that work the same way. The mapping and constraints blocks in domain classes, the grails.project.dependency.resolution block in BuildConfig.groovy, etc. All are evaluated as Groovy code, and the missing method/property calls configure GORM mappings, constraint definitions, plugin dependencies, etc.
Programming Groovy 2 is a particularly good Groovy book for learning DSLs.

Groovy Closure generic return/parameters?

I have a method that should take a Closure with first two parameters Car and Tyre and should return a type of Vehicle.
Is there a way to declare the type of parameters in Groovy Closures?
I am thinking
method(Closure<Vehicle, Car, Tyre> closure);
but what is the correct way?
You can only define the return type of a Closure, ie: Closure<Vehicle>
As of Groovy 2.3, you can use #ClosureParam to tweak the type system (see "Tweaking the type system" here), but Groovy 2.3 is not currently in Grails I believe...
The generic parameter on Closure is used for the return type. Closure<String> shall return a string.
The parameters may be declared using the #ClosureParams annotation
http://beta.groovy-lang.org/docs/groovy-2.3.0-beta-1/html/gapi/groovy/transform/stc/ClosureParams.html

Bean definition using Grails Spring DSL needs index/type/name arguments

In resources.groovy, I'm trying to define a bean named 'sql' which is a groovy.sql.Sql constructed using the dataSource defined by the application.
sql(groovy.sql.Sql, 'firstArgument', ref('dataSource') ) {}
Unfortunately this fails as follows --
Error executing script Console: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sql': Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities).
I looked at http://grails.org/doc/1.3.x/guide/14.%20Grails%20and%20Spring but there is no further information about legal syntax for specifying arguments to avoid type ambiguities beyond the example given there which uses "firstArgument".
I have tried passing "dataSource" and "javax.sql.DataSource" instead of "firstArgument", both unquoted and in double quotes but no success.
The example given in the grails documentation is misleading you. They are constructing an instance of a class with two arguments; the first being a string and the second an int. You will want something like:
sql(groovy.sql.Sql, ref('dataSource') ) {}

Dynamic method definition with GroovyDSL in IntelliJ

I was trying to define a dynamic method using the GroovyDSL scripting capabilities in IntelliJ. The starting guide "Scripting IDE for DSL awareness" gives you a good idea on how to get started with this. The dynamic method definition in my DSL is more complex than the example though and I am not quite sure how to build this. You can imagine it working like dynamic finder methods in Grails except that you can combine an arbitrary number of criteria with a boolean And keyword in any order. All keywords are not defined in the class that I am invoking the method on but could be defined in the GDSL file. The method always starts with submitTransactionWith. Here's an example:
clientDSL.submitTransactionWithCriteria1AndCriteria2AndCriteria3(arg1, arg2, arg3)
I started out with this but that only works for one criteria and doesn't take into account that you can combined multiple criteria in any order.
def ctx = context(ctype: "my.client.ClientDSL")
contributor(ctx) {
['Criteria1', 'Criteria2', 'Criteria3'].each {
method name: "submitTransactionWith${it}",
type: 'java.util.Map',
params: [args: 'java.util.Collection']
}
}
I was wondering if there's special support for that kind of dynamic method. I'd also be interested in how the DSL for Grails is modeled internally in IntelliJ.
The Grails DSL in located in ${idea.home}/plugins/GrailsGriffon/lib/standardDsls
It would probably help you for your problem. They create string arrays of all the method name combinations ahead of time, and then just iterate through them in their contributor creating a method using the arrays of strings for names.

Resources