views:

34

answers:

1

I have developed this small app and run it on Jetty with no problems...

Bug.groovy:

package itsafeature

class Bug {

    String name
    String description
    Priority priority

    Project project

    static belongsTo = Project

    static constraints = {
        name(size:10..150)
        description(size:25..1500)
        project(nullable:false)
        priority(nullable:false)
    }

    String toString() {
        return "${priority}:${name}"
    }
}
enum Priority {HIGH(5), MEDIUM(3),LOW(1)
    private Priority(int val){
        value = val
    }
    private final int value
    int value() {
        value
    }
}

When I use Netbeans to deploy directly to it's Grails Jetty Server, this works exactly as you'd expect. The Priority is written to my database as a string, and it does what I want.

However, If I take the project and do a "build", it creates a "production" build of the application (my datasource file is the same for all builds), and I put it in my "webapps" folder of a local tomcat server, and I see the following stacktrace:

SEVERE: Exception sending context initialized event to listener instance of class org.codehaus.groovy.grails.web.context.GrailsContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grailsApplication' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
        ... SNIP! ...
Caused by: java.lang.ExceptionInInitializerError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
Caused by: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: Priority(java.lang.String, java.lang.Integer)
        at Priority.<clinit>(Priority.groovy:10)
        ... 2 more

What should I be looking at to narrow down this issue? I only have one groovy installed on windows, with the GROOVY_HOME pointed to that, same with GRAILS. Does Jetty have it's own version of these runtimes? Or is this really an application server problem?

There is a grails command that says "tomcat", not sure if that has anything to do with this, but I'm not using it

+1  A: 

Move the enum to its own file in src/groovy (in the same package or another, but it can't be in the default package and be accessed by a domain class in a package).

btw - you don't need Groovy or GROOVY_HOME with Grails - it comes with the version of the Groovy jar that it works with and that gets deployed in your war.

Burt Beckwith
Soooo... I've accepted you answer, so I can offer nothing more than thanks for any response to this, but just in case you're feeling benevolent. How did you know that? Any idea why that works? If it didn't work in general, that would be one thing, but the fact that it worked on jetty and not tomcat has me all kinds of confused. Thanks again! I can finally get rid of all these lazy domain objects
walnutmon
Sorry, I have no idea why it works in Jetty. From the error it looks like the enum is being treated like a domain class since something (your stack trace is cut off) is trying to instantiate a new instance using a default constructor. Grails instantiates artifacts during startup to inspect properties and it looks like both classes are being (at least partially) treated as domain classes. So putting the enum in src/groovy or src/java gets around the problem, plus it's probably the right thing to do since it may be used from other places than just your domain class.
Burt Beckwith