Search code examples
oopgroovyreflectionclosuresgpath

Groovy : Class.forName().newInstance() error


I have this following method in which I return a List<ImField> object using the List<GPathResult> filteredList. I perform filteredList.each closure where I generate class at runtime and assign it a static type of ImField.

static List<ImField> getFields(GPathResult root,String fieldClass, String fieldType){
        List<GPathResult> filteredList = root.children().findAll{
            XMLSlurperUtil.name(it as GPathResult) == fieldType
        } as List<GPathResult>
        List<ImField> fields = []
        filteredList.each{GPathResult it,  int index ->
            fields.add(Class.forName(fieldClass).newInstance() as ImField)
            fields[index].set(it)
        }
        fields
}

The function call would look like so :

ImStageUtil.getFields(root, ImFieldFactory.SOURCE_FIELD, ImParserConstants.SOURCE_FIELD)

where ImFieldFactory.SOURCE_FIELD = "com.dto.fields.SourceField" and ImParserContants.SOURCE_FIELD = "SOURCEFIELD"

the error occurs at the .each closure line:

No signature of method: com.extractor.ImStageUtil$_getFields_closure11.doCall() is applicable for argument types: (groovy.util.slurpersupport.NodeChild) values: []
Possible solutions: doCall(groovy.util.slurpersupport.GPathResult, int), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object)
groovy.lang.MissingMethodException: No signature of method: com.extractor.ImStageUtil$_getFields_closure11.doCall() is applicable for argument types: (groovy.util.slurpersupport.NodeChild) values: []
Possible solutions: doCall(groovy.util.slurpersupport.GPathResult, int), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object)

Solution

  • I've tried to create a similar script to your example, there are two things I had to modify (if your filteredList is not empty, which you need to check first):

    1- You need to use collect() after the findAll{} closure, this allows you to collect all entries and add them to your filteredList.

    2- You're using .each{} and you're providing a List along with the index, this should be replaced by .eachWithIndex{} because the first one doesn't expect an index. Here is a simplified version of your code:

    import groovy.util.slurpersupport.GPathResult
    
    def text = '''
        <list>
            <technology>
                <name>Groovy</name>
            </technology>
        </list>
    '''
    
    def list = new XmlSlurper().parseText(text)
    
    def List getFields(GPathResult root,String fieldClass, String fieldType){
            List<GPathResult> filteredList = root.children().findAll{
                //println(it)
                it != null
            }.collect() as List<GPathResult>
    
            println('list: ' + filteredList.getClass() + ', ' + filteredList.size())
    
            filteredList.eachWithIndex{GPathResult it,  int index ->
                println('it: ' + it)
            }
    }
    
    getFields(list, '', '')
    

    This last example doesn't raise any exception for me.

    Hope this helps.