Recently I upgraded grails from 1.3.4 to 2.2.2 and I'm getting following error while trying to iterate over a Set defined as hasMany in a domain.
class A {
String name
static hasMany = [bList: B]
}
class B {
static belongsTo = [a:A]
}
class TestController {
def test = {
A a = A.get(1L)
def bList = a.bList
bList.each{}
}
}
Above line bList.each {} is throwing following exception
java.lang.IllegalArgumentException: wrong number of arguments
at
org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener.onApplicationEvent(AbstractPersistenceEventListener.java:46)
at
com.test.TestController$_closure2.doCall(TestController.groovy:5)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:680)
So I found the issue
Class B had a afterLoad() event hook attached to it which for some weird reason was throwing java.lang.IllegalArgumentException: wrong number of arguments exception I have now changed it to onLoad() Happy Days Now.
Thanks
Hussain
Related
I have migrated my application from Grails-3.x to Grails-4.1.1
Most of my Domain classes implemented the following Traits class (DynamicProperties), which has an implementation of GormEntity for some reason - to override the propertyMissing method.
trait DynamicProperties<D> implements GormEntity<D> {
def dynamic = [:]
def propertyMissing(String name, value) {
if (!propertyIsDatasource(name)) {
dynamic[name] = value
}
}
def propertyMissing(String name) {
if (propertyIsDatasource(name)) {
super.propertyMissing(name)
} else {
dynamic[name]
}
}
boolean propertyIsDatasource(String name) {
false
}
}
The above trait has been implemented by many domain classes like this
class Customer implements DynamicProperties<Customer> {
String customerCode
String customerName
Address address
....
}
Now, when I run my application, It is throwing the following exception
HHH000142: Bytecode enhancement failed: com.apps.billing.Customer.
Caused by: java.lang.NullPointerException
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:37)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:75)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at **com.apps.billing.common.DynamicProperties$Trait$Helper.$init$**(DynamicProperties.groovy:7)
It used to work fine with Grails3.x
I had a similar problem when migrating a project to Grails 4.0.13.
I tracked the trigger of this problem down to having default values for member variables in a trait class. I see you have the same with the property dynamic being initialized with the empty map.
I recommend lazy initializing it in one of your propertyMissing methods.
I have a controller like this:
class DemoController {
def index() {
DemoCommand cmd = new DemoCommand(demoAmount: 'foo')
render cmd.validate() ? "Validation successful" : "Validation failed, ${cmd.errors}"
}
}
class DemoCommand implements Validateable {
String demoAmount
static constraints = {
demoAmount nullable: false
}
Long getDemoAmountAsLong() {
demoAmount?.isNumber() ? new Long(demoAmount) : null
}
}
Hitting the index action shows validation failed, stating demoAmountAsLong cannot be null. There were a couple bugs reported in 3.1.2 (https://github.com/grails/grails-core/issues/9754) on this issue but looked like they were resolved. I've tested this in both 3.1.11 and 3.2.11 with the same results. I must be missing something? I've tried making the getter method transient, or adding static transients = ['demoAmountAsLong'] without luck.
I've got the following code:
trait ContainingClosure {
def method() {
def delegateClass = new DelegateClass()
def closure = {
methodFromDelegate()
}
closure.delegate = delegateClass
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure.call()
}
}
class DelegateClass {
def methodFromDelegate() {
println 'methodFromDelegate called'
}
}
class Main implements ContainingClosure {}
new Main().method()
The problem is that methodFromDelegate() cannot be found when I run call() method and the following exception is thrown:
groovy.lang.MissingMethodException: No signature of method: Main.methodFromDelegate() is applicable for argument types: () values: []
Is there any reasonable explanation why this snippet is not working in Grails 2.5.0 (Groovy 2.4.3)? It seems that the delegate of the closure is somehow ignored and method lookup is done in Main class scope not the delegate itself.
Changing trait into class and implementation of a trait into inheritance makes this code working again.
Found it, it's this bug
https://issues.apache.org/jira/browse/GROOVY-7456
Which is fixed in groovy 2.4.4, so an upgrade of grails should fix it :-)
I assume that the issue involves the creation of the Groovy console inside the Grails instance; normal Domain object queries work fine, but attempting to query into a self-referential one-to-one causes issues.
I have a Domain class like the followng:
package demo
class Foo {
String name
static hasMany = [substitutes: Foo]
static constraints = {
}
}
During bootstrap, I create a Console to be able to inspect the domain objects:
import demo.Foo
import org.springframework.web.context.support.WebApplicationContextUtils
import org.codehaus.groovy.grails.commons.GrailsApplication
import grails.util.GrailsUtil
import groovy.ui.Console
class BootStrap {
def init = { servletContext ->
def one = new Foo([name: 'one'])
def two = new Foo([name: 'two'])
[one,two].each { it.save(failOnError: true, flush: true)}
one.addToSubstitutes(two)
one.save(failOnError: true, flush: true)
def appCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
def grailsApp = appCtx.getBean(GrailsApplication.APPLICATION_ID);
Binding b = new Binding();
b.setVariable("ctx", appCtx);
def console = new Console(grailsApp.classLoader, b);
console.run()
Foo.list().each{println it.name}
Foo.list().each{println it.substitutes}
println '--------------------------'
}
def destroy = {
}
}
This prints the following in the console:
one
two
[demo.Foo : 2]
null
--------------------------
Within the console, I attempt to repeat the two queries, which throws an exception:
groovy> import demo.Foo
groovy> demo.Foo.list().each{println it.name}
groovy> demo.Foo.list().each{println it.substitutes}
one
two
Exception thrown
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: demo.Foo.substitutes, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243)
at ConsoleScript2$_run_closure2.doCall(ConsoleScript2:3)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243)
at ConsoleScript2.run(ConsoleScript2:3)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243)
Grails 2.2
So this should be pretty easy, however I am constantly getting the same error message:
Class java.lang.IllegalArgumentException
Message No enum constant myPackageName.RequestType.Banner
Here is my class:
public enum RequestType {
BANNER("Banner"), OTHER("Other")
final String value
RequestType(String value) { this.value = value }
String toString() { value }
}
This is driving me up the wall!!
Edit: Stacktrace
No enum constant myPackageName.RequestType.Banner. Stacktrace follows:
java.lang.IllegalArgumentException: No enum constant myPackageName.RequestType.Banner
at java.lang.Enum.valueOf(Enum.java:236)
at org.grails.datastore.gorm.GormStaticApi.methodMissing(GormStaticApi.groovy:108)
at ysuprojects.ProjectService.viewableProjects(ProjectService.groovy:115)
at ysuprojects.ProjectService.getIndexModel(ProjectService.groovy:422)
at ysuprojects.ProjectController.index(ProjectController.groovy:25)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Here is how it is used in the class
class Project {
...
RequestType requestType
...
}
Ok - so here is what happened.
I switched from using a String to using an Enum. The existing database had "Banner" in the field, which was causing this error. I changed the field to "BANNER" and I no longer receive this error.
Grails was attempting to do Enum.valueOf(RequestType, "Banner")