The NotFound class is considered strange

ClassNotFound (yes, I know there are many posts about this exception, I searched here and elsewhere and could not find an explanation)

Why is Class.forName not working?

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!

+4
source share
2 answers

This is due to ClassLoader. The Loader class inside the shell (i.e. the classes that you define inside the shell) is different from the ClassLoader class, which launches the shell (the banks you need to run the shell). So the Class.forName("Foo", true, this.class.classLoader) command Class.forName("Foo", true, this.class.classLoader) works because you specify the ClassLoader inside the shell

to try

 def shell=new GroovyShell() def f=shell.evaluate("class Foo{Foo(){println this.class.classLoader}};def f=new Foo()") println shell.class.classLoader shell.evaluate("println this.class.classLoader") println "-----------" println Class.forName("Foo", true, f.class.classLoader) println Class.forName("Foo", true, this.class.classLoader) 

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 use the ClassLoader shell

Doing Class.forName will not use the same thing as this in the context of your script.

Not sure if this is clear enough :(

+2
source

This answer is basically right, but it lacks one important information bit. Class.forName(String) is a Java method for Java that is called from Java. To load this class, you must load the class loader. And it gets the bootloader using an internal method to raise the call stack. Although for java going up one level, the right thing to work fine is not the case in Groovy. Each method call in Groovy can contain a variable number of elements of the intermediate call stack from the generated methods, from invokedynamic, from reflection. But usually the frame of the parent call stack does not contain the real class of the caller. Instead, you end up in the loader for the Groovy runtime, or even in the loader for the java runtime. The class in your shell is in the child, so the loader cannot find the requested class.

+3
source

Source: https://habr.com/ru/post/1440179/


All Articles