NOTE
This is not a Groovy related problem, but I’m using it to illustrate my problem and solution here.
PROBLEM
I recently tried mixing some Groovy code into my existing JEE project. I created a simple POGO that looks as sophisticated as this:-
class GroovyStuff {
String name
}
Then, I configured one of my controllers to invoke that POGO:-
@Controller
@RequestMapping(value = "/")
public class HomeController {
@RequestMapping(method = RequestMethod.GET)
public String main() {
GroovyStuff stuff = new GroovyStuff();
stuff.setName("Hello Groovy");
System.out.println(stuff.getName());
return "home";
}
}
After starting up Jetty, I hit that controller from the web and I get this infamous exception:-
java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.findBootstrapClass(Native Method)
at java.lang.ClassLoader.findBootstrapClassOrNull(ClassLoader.java:926)
at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:407)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:383)
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2475)
at java.lang.Class.getDeclaredMethods(Class.java:1818)
at org.codehaus.groovy.reflection.CachedClass$3$1.run(CachedClass.java:84)
at java.security.AccessController.doPrivileged(Native Method)
at org.codehaus.groovy.reflection.CachedClass$3.initValue(CachedClass.java:81)
at org.codehaus.groovy.reflection.CachedClass$3.initValue(CachedClass.java:79)
at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
at org.codehaus.groovy.util.LazyReference.get(LazyReference.java:33)
at org.codehaus.groovy.reflection.CachedClass.getMethods(CachedClass.java:250)
at org.codehaus.groovy.runtime.m12n.SimpleExtensionModule.createMetaMethods(SimpleExtensionModule.java:111)
at org.codehaus.groovy.runtime.m12n.SimpleExtensionModule.getMetaMethods(SimpleExtensionModule.java:93)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerExtensionModuleFromProperties(MetaClassRegistryImpl.java:192)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerExtensionModuleFromMetaInf(MetaClassRegistryImpl.java:174)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerClasspathModules(MetaClassRegistryImpl.java:156)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:111)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:73)
at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:33)
at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:162)
at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:192)
at myproject.bean.GroovyStuff.$getStaticMetaClass(Stuff.groovy)
at myproject.bean.GroovyStuff.<init>(Stuff.groovy)
at myproject.controller.HomeController.main(HomeController.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
I tried both GMaven Plugin and Groovy-Eclipse Compiler Plugin, and both gave me the same problem.
I checked my MAVEN_OPTS
variable, and I have set a rather big max perm size, but it doesn’t fix the problem.
export MAVEN_OPTS="-Xms2048m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m"
Then, I rebooted my laptop since that’s what most tech supports in the world would tell me to do when they encounter a problem… but it doesn’t fix the problem.
When I commented out the Groovy calls from the controller, everything works fine:-
@Controller
@RequestMapping(value = "/")
public class HomeController {
@RequestMapping(method = RequestMethod.GET)
public String main() {
//GroovyStuff stuff = new GroovyStuff();
//stuff.setName("Hello Groovy");
//System.out.println(stuff.getName());
return "home";
}
}
After venting my frustration at the ping pong table and cursing at the laptop for many hours both at work and at home, I decided to run Jetty directly from the command line:-
mvn clean jetty:run
I was rather surprised that I no longer see the error.
SOLUTION
After poking around, I realized that IntelliJ doesn’t seem to honor my MAVEN_OPTS
setting. When I run jetty:run
goal from IntelliJ, I see the following output in the console:-
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java
-Dmaven.home=/usr/local/apache-maven-3.0.3 -Dclassworlds.conf=/usr/local/apache-maven-3.0.3/bin/m2.conf
-Didea.launcher.port=7533 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 12.app/bin"
-Dfile.encoding=UTF-8 -classpath "/usr/local/apache-maven-3.0.3/boot/plexus-classworlds-2.4.jar:/Applications/IntelliJ IDEA 12.app/lib/idea_rt.jar"
com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher --fail-fast --strict-checksums
org.mortbay.jetty:jetty-maven-plugin:8.1.8.v20121106:run
So, I went to IntelliJ’s Preferences... -> Maven -> Runner
and set my MAVEN_OPTS
values under VM Options
:-

When I run jetty:run
goal from IntelliJ again, now I see the following output in the console:-
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java
-Xms2048m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m
-Dmaven.home=/usr/local/apache-maven-3.0.3 -Dclassworlds.conf=/usr/local/apache-maven-3.0.3/bin/m2.conf
-Didea.launcher.port=7534 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 12.app/bin"
-Dfile.encoding=UTF-8 -classpath "/usr/local/apache-maven-3.0.3/boot/plexus-classworlds-2.4.jar:/Applications/IntelliJ IDEA 12.app/lib/idea_rt.jar"
com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher --fail-fast --strict-checksums
org.mortbay.jetty:jetty-maven-plugin:8.1.8.v20121106:run
Now, when I hit my controller again, the error went away.
The moral of the story is… if you still cannot fix your coding problem after spending many hours, go play ping pong.