simple problem. Wanted to load classes dynamically based on a domain instance name.
Simple (in theory)
String name="Domain"
String className = "com.package.test."+name+"Service"
Object o =Class.forName(className).newInstance()
But it fails with a ClassNotFoundException. (and of course the class does exist).
After a lot of tested I came to the following answer
Object o = Thread.currentThread().contextClassLoader.loadClass(className).newInstance()
or
Object o = SomeOtherService.getClassLoader().loadClass(className).newInstance()
Why I don't know. One tends to work in unit tests and not in application code, and the opposite for the other, so often I include both
Here's some links that may help explain.
http://groovy.dzone.com/news/class-loading-fun-groovy
Based on this I wrote a simple test to check the different class loaders
def testB(){ parseCL(this.getClass().getClassLoader()) //This ClassLoader does NOT work parseCL(AnotherService.getClassLoader()) // This class Loader does work } def parseCL(ClassLoader cl){ println "********************" println cl println "********************" println "Parent ="+cl.getParent() cl = cl.getParent() def indent = "--" while(cl){ println indent+cl cl = cl.getParent() println indent+"Parent ="+cl indent = indent +"--" } }
Note the top level classloader is different
******************** java.net.URLClassLoader@247510e7 // DOES NOT LOAD CLASS DYNAMICALLY ******************** Parent =java.net.URLClassLoader@77479ef9 --java.net.URLClassLoader@77479ef9 --Parent =org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd ----org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd ----Parent =sun.misc.Launcher$AppClassLoader@35a16869 ------sun.misc.Launcher$AppClassLoader@35a16869 ------Parent =sun.misc.Launcher$ExtClassLoader@77cde100 --------sun.misc.Launcher$ExtClassLoader@77cde100 --------Parent =null ******************** java.net.URLClassLoader@77479ef9 // LOADS CLASS DYNAMICALLY ******************** Parent =org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd --org.codehaus.groovy.grails.cli.support.GrailsRootLoader@15ded0fd --Parent =sun.misc.Launcher$AppClassLoader@35a16869 ----sun.misc.Launcher$AppClassLoader@35a16869 ----Parent =sun.misc.Launcher$ExtClassLoader@77cde100 ------sun.misc.Launcher$ExtClassLoader@77cde100 --------Parent =null
1 comment:
Thanks a lot!
Post a Comment