blue_giraffe
blue_giraffe

Reputation: 33

java.lang.IllegalStateException = confused newbie

A confused Grails newbie here. I am currently going through the tutorials in a book (Smith, Ledbrook, "Grails in Action", Manning Publications, 1st Ed) and am stumped in the first chapter! When browsing to localhost, I get the error messages further below. The tutorial leads me through creating a Random Quote of the Day application. As you might suspect, browsing to the webpage gives a random quote (which were saved in the "Quote" domain class) with each refresh.

I have made the controller, view, layout, domain class, all of which are pretty simple. I would imagine that I'd get these errors if there were no test data, but using the grails console shows me that there are. Despite this, refreshes of the browser echo the errors in an open terminal.

The code for the Quote domain class and the controller are below as well. I wanted to change the config file for the development environment to make it persistent, so that entry is also down there. Let me know if you need to see anything else...

Any ideas? (Using Grails version 2.4.0 installed on Ubuntu 14.04. Book uses code for Grails 1.1)

Error:

URI: /qotd/quote/random

Class:java.lang.IllegalStateException

Message: Method on class [qotd.Quote] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.

Around line 8 of grails-app/controllers/qotd/QuoteController.groovy
6:
7:      def random = {
8:              def allQuotes = Quote.list()
9:              /*def randomQuote
10:             if (allQuotes.size() > 0 )
11:             {

Trace
    Line | Method
->>    9 | doCall    in QuoteController.groovy
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|    198 | doFilter  in PageFragmentCachingFilter.java
|     63 | doFilter  in AbstractFilter.java
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    744 | run       in java.lang.Thread

Controller

package qotd

class QuoteController {

        def index = { }

        def random = {
                def allQuotes = Quote.list()
                /*
                def randomQuote
                if (allQuotes.size() > 0 )
                {
                        def randomIdx = new Random().nextInt(allQuotes.size())
                        randomQuote = allQuotes[randomIdx]
                } else {
                        randomQuote = new Quote(author: "Anonymous",
                                content: "Real Programmers Don't eat Quiche")
                }
                [quote : randomQuote ]
                */

        }
}

Quote domain class

package qotd

class Quote {

        String content
        String author
        Date created = new Date()

    static constraints = {
    }
}

Development Environment from DataSource.groovy

    development {
        dataSource {
            dbCreate = "update" // one of 'create', 'create-drop', 'update',
'validate', ''
            url =
"jdbc:h2:file:~/h2db/quotedevdb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
        }
    }

Upvotes: 3

Views: 836

Answers (1)

augustearth
augustearth

Reputation: 291

Yep, as grantmcconnaughey comments, you don't want to declare your controller actions as closures with an '=' sign. It is now recommended to use methods. So you can do:

def random() {
    def allQuotes = Quote.list()
}

or:

public random() {
    def allQuotes = Quote.list()
}

See the online docs.

Upvotes: 3

Related Questions