Please help me to fix this issue. Thank you!
I am working on a Grails-5.2.4 project with Java 1.8. Class Loader is not working as expected.
I am getting class cast exception for the following piece of code.
def index() {
Profile profile = getClass().classLoader.loadClass("centaur.demo.Profile") as Profile
}
Below is the exception details:
Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class centaur.demo.Profile' with class 'java.lang.Class' to class 'centaur.demo.Profile'
at org.grails.web.converters.ConverterUtil.invokeOriginalAsTypeMethod(ConverterUtil.java:147)
at org.grails.web.converters.ConvertersExtension.asType(ConvertersExtension.groovy:56)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at centaur.demo.IndexController.index(IndexController.groovy:10)
... 13 common frames omitted
Expected behavior:
The line below should return an object of class Profile.
getClass().classLoader.loadClass("centaur.demo.Profile")
This is working fine with Grails 3.3.9.
CodePudding user response:
As the name suggests ClassLoader#loadClass
returns an instance of java.lang.Class
. You have to instantiate the class to get an object of its referenced type using new Profile(...)
or by calling Class#newInstance
on the result of loadClass
(provided your Profile class has an accessible default constructor)
CodePudding user response:
this line:
getClass().classLoader.loadClass("centaur.demo.Profile")
should return you a Class
object.
check out the documentation: https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html#loadClass-java.lang.String-
so, you could assign result to Class:
Class c = getClass().classLoader.loadClass("centaur.demo.Profile")
you could instantiate class:
def profile = getClass().classLoader.loadClass("centaur.demo.Profile").newInstance()
but the following code could fail:
centaur.demo.Profile profile = getClass().classLoader.loadClass("centaur.demo.Profile").newInstance()
when class loader used for declaration is different from the one returned by getClass().classLoader