Question

I have a grails application which is failing at runtime in a cryptic way (cyptic to me anyway) with a ArrayIndexOutOfBoundsException when I visit the scaffolded /imca2/imcaReferral/index.

* now edited to put solution at end *

There are about a dozen domain classes. I haven't got round to worrying about the UI yet so the controllers are all dynamically scaffolded.

All the other controllers work OK.

This Controller:

package com.ubergen
class ImcaReferralController {
    def scaffold = ImcaReferral
}

For this Domain:

package com.ubergen
class ImcaReferral {
    private def todayDate = new Date()
    String          advocacyReferenceNum        = ""
[snip a lot of code]
    String toString() {
        "${this.advocacyReferenceNum}: ${this.client?this.client:'-'}${this.referralIssue?', '+this.referralIssue:''}"
    }
}

(I don't want to post the domain class here as its huge).

Produces this stacktrace:

|Server running. Browse to http://localhost:8080/imca2
| Error 2014-03-12 18:48:24,935 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver  - ArrayIndexOutOfBoundsException occurred when processing request: [GET] /imca2/imcaReferral/index
0. Stacktrace follows:
Message: 0
    Line | Method
->>   55 | <init>     in grails.orm.PagedResultList
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|     15 | $tt__index in com.ubergen.ImcaReferralController
|    191 | doFilter . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter   in grails.plugin.cache.web.filter.AbstractFilter
|   1146 | runWorker  in java.util.concurrent.ThreadPoolExecutor
|    615 | run        in java.util.concurrent.ThreadPoolExecutor$Worker
^    701 | run . . .  in java.lang.Thread

Cleaning and (re)compiling make no difference.

The domain class is being used during bootstrapping to push data successfully into the database, so it works to that extent.

I can run the application from the command line instead of from inside eclipse/STS. The same error is thrown.

run-app --noreloading makes no difference either (clutching at straws now). And run-war also produces the same error.

run-app --verbose shows:

| Error 2014-03-12 19:58:37,745 [http-bio-8080-exec-1] ERROR errors.GrailsExceptionResolver  - ArrayIndexOutOfBoundsException occurred when processing request: [GET] /imca2/imcaReferral/index
0. Stacktrace follows:
java.lang.ArrayIndexOutOfBoundsException: 0
    at org.hibernate.criterion.Order.toSqlString(Order.java:73)
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.getOrderBy(CriteriaQueryTranslator.java:394)
    [snip]
    at grails.orm.PagedResultList.<init>(PagedResultList.java:55)
    [snip]
    at com.ubergen.ImcaReferral.list(ImcaReferral.groovy)
    [snip]
    at com.ubergen.ImcaReferralController.$tt__index(script1394654146228610896735.groovy:15)
    [snip]

So the index page calls the domain's list() and this is a problem in some way but not enough of a way that its getting mentioned in the stacktrace.

Where should I look first for the problem?

Versions:

ubuntu 10.04
eclipse / SpringToolSuite 3.4.0
grails 2.3.6
groovy 2.1.9 (for both project and workspace)

Update 13/03/2014

I followed Joe's suggestions (below) and found that the problem is indeed in the ImcaReferral.list() method.

In the grails console simply running:

package com.ubergen
ImcaReferral.withTransaction { status -> 
    ImcaReferral.list()
 } 

Returns

java.lang.ArrayIndexOutOfBoundsException: 0
at org.hibernate.criterion.Order.toSqlString(Order.java:73)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getOrderBy(CriteriaQueryTranslator.ja a:394)
[snip]
at com.ubergen.ImcaReferral.list(ImcaReferral.groovy)

Looking at the domain's sort order information BINGO! its incorrectly defined, there are two competing definitions of how to sort the domain.

I Comment out the erroneous sort order information:

package com.ubergen
class ImcaReferral {
    ...
    static hasMany = [challenges:Challenge]
    static mapping = {
         ...
         sort dateReceived:'asc' 
      // sort challenges:'challengeRoute'   // *** ERROR ***
    }
}

and (after restarting the console) the call to list works fine and returns an empty array.

Correcting the sort order of the child records:

package com.ubergen
class ImcaReferral {
    ...
    static hasMany = [challenges:Challenge]
    static mapping = {
        ...
        sort dateReceived:'asc' 
        challenges sort: 'challengeRoute', order: 'asc' // *** CORRECT ***
    }
}

Fixes the problem. The scaffolding now works.

Conclusions

  1. Trust the full stacktrace even if its rather verbose. It shows the classes and methods to look at.

  2. Learn to use the console.

    grails -reloading console

  3. Read your more code carefully!

Was it helpful?

Solution

You could try to generate the Static Scaffolding and see if you get a different result. You could also try running the list in a integration test to see what happens.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top