Search code examples
javaservletsexceptioninitfactories

How to throw exceptions for the init() method for servlets


well I'll first show my code:

@Override
public void init() throws ServletException {
    super.init();

    try {
        securityController = SecurityControllerFactory.getInstance().create();
    } catch (Exception e) {
        System.err.println("Error creating security controller; " + e.getMessage());
    }

    // max allowed uploaded uploadedFile size is 10 MB
    maxFileSize = getBytes(10);
    maxMemSize = getBytes(2);
}

As you can see the compiler is forcing me to use try/catch for instantiating the SecurityController. In my case however I believe it should stop instantiating the Servlet and throw an exception in general if the security controller can't be instantiated. Any suggestions/explanations to this?


Solution

  • Carefully read the javadoc of init() method:

    init

    public void init() throws ServletException

    ...

    Throws:

    ServletException - if an exception occurs that interrupts the servlet's normal operation

    Look there, you're supposed to rethrow it as ServletException. Conform chapter 2.3.2.1 of the Servlet API specification, the servlet will not be placed in service:

    2.3.2.1 Error Conditions on Initialization

    During initialization, the servlet instance can throw an UnavailableException or a ServletException. In this case, the servlet must not be placed into active service and must be released by the servlet container. The destroy method is not called as it is considered unsuccessful initialization.

    ...

    Thus, just do what the docs state (this is the normal process, by the way, you should as being a Java beginner understand/realize that very good):

    @Override
    public void init() throws ServletException {
        try {
            securityController = SecurityControllerFactory.getInstance().create();
        } catch (Exception e) {
            throw new ServletException("Error creating security controller", e);
        }
    
        maxFileSize = getBytes(10);
        maxMemSize = getBytes(2);
    }
    

    Please note that I removed the unnecessary super.init() call. The javadoc isn't telling anywhere that you're required to do that for init(), only for init(ServletConfig).


    Unrelated to the concrete problem, having an overly generic catch on Exception is considered poor practice. You certainly don't want to cover RuntimeExceptions with your overly generic catch on Exception as that may unintentionally hide away programmer's mistakes/bugs.

    You should try to be as specific as possible in your catch, try to catch as specific as possible the exception(s) being declared in throws of those methods. For example:

        try {
            securityController = SecurityControllerFactory.getInstance().create();
        } catch (SecurityControllerCreationException e) {
            throw new ServletException("Error creating security controller", e);
        }
    

    Another cause could also be that the methods in question are so badly designed that they are by themselves declared as throws Exception. You should in turn fix that part as well.