A null pointer exception caused by a cglib proxy

Source: Internet
Author: User

A colleague partially modified the company's development framework based on the latest spring, tomcat, and Java versions. After the development and running, he found a strange NULL pointer exception.

To restore the current scenario, the code is roughly as follows. All servlets inherit from baseservlet. Take DefaultServlet as an example. When a defaservlet Servlet request arrives, it is mapped to a servletproxy Servlet and then forwarded to defaservlet servlet. The setlogger method of DefaultServlet has been called before forwarding. Assuming that the method is forwarded to the doget method, the doget method first calls response (req, Res) and forwards it to the execute method. The execute method prints a line of log, no problem at this point. Next, the doget method also prints a line of log "@ doget". a null pointer exception is reported here. It is strange that logger is null. How can it be null.

Public abstract class baseservlet extends httpservlet {protected log logger; @ override public final void doget (httpservletrequest req, httpservletresponse res) throws ioexception {response (req, Res); logger. debug ("@ doget");} @ override public final void dopost (httpservletrequest req, httpservletresponse res) throws ioexception {response (req, Res); logger. debug ("@ dopost");} private void response (httpservletrequest req, httpservletresponse res) throws ioexception {string result = ""; try {result = execute (req, Res);} finally {// returned result} public void setlogger (log logger) {This. logger = logger;} public abstract string execute (httpservletrequest req, httpservletresponse res) throws ioexception;} public class DefaultServlet extends baseservlet {@ override Public String execute (httpservletrequest req, destination res) throws ioexception {logger.info ("@ defaservlet servlet ");}}

After a while, I couldn't find a reason. Finally, I compared it with the original framework and found that doget and dopost were added with the final modifier. I am going, so I have a clue, because dynamic proxy is configured in the spring configuration file. Cglib is used for dynamic proxy.

Next, let's take a look at the general principle of cglib (for some components of speculation, please correct them). Suppose there is a Class A. If cglib is used as a dynamic proxy, A Class B is dynamically generated and loaded at the bytecode level. The simulation code is as follows. B inherits from a and references a at the same time. All override methods of Class B must be rewritten and the same name method of type A target must be called, of course, the pre-call and post-call operations can be performed before the target method is called. This is the purpose of the proxy. This is omitted here.

In the main function, a new class B instance is added and the setname method is called. In fact, the setname method of target is executed, and the field name of target is set, the field name of instance B is still empty. Calling the notfinalmethod method also calls the target method and prints the name of the target field. However, because the finalmethod method has a final modifier, it cannot be rewritten in B. When the finalmethod method is called, The finalmethod method of B can only be called, instead of the finalmethod method of target, at this time, because the name of instance B is empty, the printed value is empty.

public class CGLibSimulate {    public static void main(String[] args) {        A a=new B();        a.setName("aa");        a.notFinalMethod();        a.finalMethod();    }    public static class A {        protected String name = null;                public final void finalMethod() {            System.out.println(name);        }        public void notFinalMethod() {            System.out.println(name);        }                public void setName(String name){            this.name=name;        }    }    public static class B extends A {        private A target=new A();                @Override        public void notFinalMethod() {            target.notFinalMethod();        }                @Override        public void setName(String name){            target.setName(name);        }    }}

If you understand this, you should understand the cause of the above NULL pointer problem. I hope it can help people who encounter this problem.

A null pointer exception caused by a cglib proxy

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.