Problem
Problem Description: In the program code, execute the following statement: Object mapperobj = Class.forName (mapperclassname). newinstance (); Mapperinterface mapper = (mapperinterface) mapperobj; Newspaper ClassCastException.
Bug fix:1. Obtain the Classloader:mapperObj.getClass () getClassLoader () of the mapperobj and Mapperinerface.class under the operating environment respectively: Sun.misc.launcher$appclassloader MapperInterface.class.getClass (). getClassLoader (): WebContainerClassLoader2. By the JVM classload mechanism, the JVM load class is divided into four levels: the first layer is Bootstrapclassloader: The primary responsibility is the load Rt.jar such as the JVM must be in the jar package of the class. The second layer is Extclassloader: it is primarily responsible for all classes in which the load is placed in the path (default%java_home%/lib/ext) of the Java.ext.dirs attribute value. Its implementation class is sun.misc.launcher$ Extclassloader The third layer is Systemclassloader: the class responsible for the load being placed in the classpath path. Its implementation class is generally sun.misc.launcher$appclassloader the fourth layer is Appclassloader: The Application designer inherits the ClassLoader and implements the corresponding user-defined ClassLoader. A class that is known to be loaded according to the application's needs is not designed.
Detailed load strategy I do not write more, a lot of articles have, in short, two words: When define a class, low-level classloader will ask the upper level whether has been define, there is directly to use; When the load a class, At the same low level to ask if you can find, can be used directly.
Therefore, due to the original system reasons, Mapperobj was systemclassloader define, and the interface used here is Appclassloader webcontainerclassloader define. So it can cause classcastexception errors. Instanceof can also be found that mapperobj is indeed not an instance of Mapperinterface.
Because of the original system reason, unable to change other code to complete the replacement of Mapperobj Classload action, and run to the current code, Mapperobj has been define, so the Forname method can not be changed by the parameters of its class loader, The following code cannot call its methods.
Workaround: Use class reflection, replace the attribute with object definition to connect mapperobj; In the following code, use the Mapperobj.getclass (). GetInterface () method to determine if it inherits Mapperinterface. It then invokes its method with reflection. Cases:
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.