質問

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?

役に立ちましたか?

解決

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.

他のヒント

Or you can wrap them in a ServletException:

try {
    securityController = SecurityControllerFactory.getInstance().create();
} catch (Exception e) {
    throw new ServletException ("Failed to create controller.", e);
}

However it's not good form to just catch Exception, you should be catching just the specific one that is thrown by the create method.

If you really want to throw them you can throw a runtime exception:

try {
   //do stuff
} catch (Exception e) {
   throw new RuntimeException("There was an exception initializing the servlet:  ", e);
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top