ClassNotFound (yes, I know, there are lots of posts about this exception; I searched here and elsewhere and could not find an explanation)
Why does Class.forName fail?
groovy> class Foo {
groovy> }
groovy> def f = new Foo()
groovy> def cname = f.getClass().getName()
groovy> def p = f.getClass().getPackage()
groovy> def l = f.getClass().getClassLoader()
groovy> println "Foo class name: $cname"
groovy> println "Foo package: $p"
groovy> println "Foo class loader: ${f.getClass().getClassLoader().toString()}"
groovy> println "Current class loader: ${this.getClass().getClassLoader().toString()}"
groovy> try {
groovy> Class.forName(cname)
groovy> } catch (Exception e) {
groovy> println e
groovy> }
groovy> l.findClass("Foo")
Foo class name: Foo
Foo package: null
Foo class loader: groovy.lang.GroovyClassLoader$InnerLoader@2d275595
Current class loader: groovy.lang.GroovyClassLoader$InnerLoader@2d275595
java.lang.ClassNotFoundException: Foo
Exception thrown
Oct 16, 2012 4:43:28 PM org.codehaus.groovy.runtime.StackTraceUtils sanitize
WARNING: Sanitizing stacktrace:
java.lang.ClassNotFoundException: Foo
Thanks!
This is due to the ClassLoader. The ClassLoader inside the the shell (ie the classes you define inside the shell) is different from the ClassLoader that runs the shell (the jars that you need to run the shell). That is why, the command
Class.forName("Foo", true, this.class.classLoader)works, because you specify the ClassLoader inside the shelltry
You will see that the first Class.forName works, not the second. running the script is similar because it will create a script class that does not share the shell’s ClassLoader
Doing Class.forName won’t use the same this as this in the context of your script.
Not sure it is clear enough 🙁