Search code examples
javainheritancemethodssubclassprotected

How do I get a subclass to use a parent class' protected methods?


I'm writing a front controller servlet class for webapps. The front controller is designed to differentiate between three basic cases:

  1. File request (calling a FileRequestHandler instance)
  2. Data request (calling a DataRequestHandler instance)
  3. Servlet request (calling a ServletRequestHandler instance)

For testing I wanted to use Tomcat's DefaultServlet (javadoc,source code) to serve files but I cannot get it to work. The problem is that even though my FileRequestHandler class should properly extend the DefaultServlet I cannot access its protected methods (specifically doGet for handling GET requests). The classes are in different packages btw.


Code:

public class FileRequestHandler extends DefaultServlet {

// fields

    private static final long serialVersionUID = 1L;

// methods

    public void setResponse(HttpServletRequest request , HttpServletResponse response, URI uri) 
            throws IOException, ServletException 
    {
                                                                                                                                    /* DEBUG */try {
            System.out.println("(!!) doGet >> " + DefaultServlet.class.getMethod("doGet",new Class[]{HttpServletRequest.class,HttpServletResponse.class}) ) ;
            doGet(request,response) ;
                                                                                                                                    /* DEBUG */}
                                                                                                                                    /* DEBUG */catch(Exception e) { System.out.println("(!) " + this.getClass( ).getName( ) + " >> buildResponse >> " + e.toString( ) ) ; }
    }

 }

Stack trace:

(part leading up to the NullPointer)

at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:741) at org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:398) at org.pulse.web.FileRequestHandler.buildResponse(FileRequestHandler.java:39)


Update:

I maybe have to clarify that the front controller servlet will intercept all HttpRequests, (<url-pattern>/</url-pattern> in web.xml) to the effect that DefaultServlet instantiated by the servlet container will not receive any requests, as far as I can tell. I have now explicitely called DefaultServlet#init in the front controller class:

 FileRequestHandler fileRequestHandler = new FileRequestHandler( ) ;
 fileRequestHandler.init( ) ;

Now I end up with a 404 Servlet is not available.

Update2: The problem -- as turns out -- actually is a follow-up problem with inadequate use of the extended class rather than a direct problem with inheritance.


The post to the Log which I added to detect the problem's root will provoke a NoSuchMethodException.. If I omit it I'll get a NullPointerException.

It looks ever so simple. Still I can't get it to work the way I want it to. Any ideas, suggestions or insights?

TIA,

FK


Solution

  • Class.getMethod returns public methods - there's no such public method, hence the exception. You can use getDeclaredMethod to get non-public methods.

    It's not clear why you were getting a NullPointerException when you tried it without the logging - if you can post a fuller stack trace, it may be clearer.

    EDIT: Judging by the source code for DefaultServlet it looks like this is the line throwing the exception:

    CacheEntry cacheEntry = resources.lookupCache(path);
    

    That doesn't make much sense though, as init() should have thrown an exception in that case... is there anything else reporting an error in your logs?