Meaningless Drivel is fun!*
The moose likes Servlets and the fly likes How should I handle this exception? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "How should I handle this exception?" Watch "How should I handle this exception?" New topic
Author

How should I handle this exception?

Aaron John
Ranch Hand

Joined: May 30, 2005
Posts: 74
I have a class that implements ServletContextListener. The method contextInitialized(ServletContextEvent sce) is implemented so that when the context is initialized the application will load property values from a property file, like so:



So loadProperties() will examine a properties file and load all the property values from the file into a Properties object. It will put this Properties object in the ServletContext, so that the properties are made available throughout the application. If the properties file is not found anywhere, loadProperties() throws a FileNotFoundException. The contextInitialized() method catches the IOException, and simply logs the error. However the contextInitialized() method doesn't declare an exception, so I cannot rethrow another exception indicating that the property file is missing. I was thinking of wrapping the IOException and throwing a RuntimeException, because it is an unchecked exception, but it just doesn't seem like the right thing to do since you'd normally throw RuntimeExceptions for programming errors, whereas this is something that you can recover from, hence a checked exception is more appropriate.

What do others think??? Obviously if the properties object isn't set in the context, the application won't have properties values and will need to be reloaded through another context initialization.
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12678
    
    5
I would probably throw a javax.servlet.UnavailableException with an informative message.

Bill


Java Resources at www.wbrogden.com
Aaron John
Ranch Hand

Joined: May 30, 2005
Posts: 74
Originally posted by William Brogden:
I would probably throw a javax.servlet.UnavailableException with an informative message.

Bill


How can I throw this type of Exception, if the method doesn't allow any exceptions to be declared in the method signature?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
You can't. You can only throw some kind of RuntimeException, or an Error. I would usually prefer to make a custom subclass of RuntimeException, so that anyone who wants to catch it can catch it without accidentally catching other RuntimeExceptions like NullPointerException.

However, does throwing an exception here make a difference? It's not clear to me from the specification that throwing an exception in the listener will stop the servlet from being instantiated. It's possible that notification could happen in a separate thread from the servlet instantiation. You might simply prevent any other listeners from beign notified. The fact that there's no checked exception declared by the method means that other components aren't expecting any exception to be thrown here. You can't really be sure how they'll react. I recommend testing this to see - what happens if you throw an exception here? Be aware, though, that the result you get may depend on your web server. (Or maybe it's well-defined in a spec somewhere; I don't really know.)

In general, yes there are times when there is really no point in proceeding after an exception. And in this cases, it may be a valid option to convert the exception to some kind of RuntimeException, or even Error. But be aware that this may not have the desired effect - try it and see. It may be that the best you can do is log the error, and solve the problem when someone looks at the log.

Another possibility you might consider is to use setAttribute() to set some sort of flag in the context. Then the servlet could later retrieve this in the init() method to understand why it's not working. The init() method can then throw UnavailableException to signal that the servlet was never initialized. In fact, the way you've got it written, you don't need any extra flag. Just check if the applicationProperties attribute is null - if it is, then something went wrong in the listener, before the properties got loaded and put in the context.

Having said that though, why not load the properties in the init() method, rather than the ServletContextListener? That way, you can easily throw the UnavailableException in a place where it's expected, where the container will be able to take appropriate action.
[ January 23, 2008: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60053
    
  65

Since a context listener is invoked outside the scope of any particular servlet, and called prior to any servlets being loaded, it wouldn't make much sense to throw an UnavailableException (even if you could).

I tend to do something along the lines of what Jim suggested. The purpose of my context listeners is generally to set up something (or somethings) in the application context for the rest of the app, including servlets, to use. If loading fails, I log the problem and quietly move along. When the servlet init methods start firing at a later time, any servlet that depends upon this info will check if it is there or not. If not, it logs the problem and it throws an UnavailableException to prevent the servlet from being put into service.

When that happens I can check the logs to see the source of the problem.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Aaron John
Ranch Hand

Joined: May 30, 2005
Posts: 74
Originally posted by Jim Yingst:
You can't. You can only throw some kind of RuntimeException, or an Error. I would usually prefer to make a custom subclass of RuntimeException, so that anyone who wants to catch it can catch it without accidentally catching other RuntimeExceptions like NullPointerException.

However, does throwing an exception here make a difference? It's not clear to me from the specification that throwing an exception in the listener will stop the servlet from being instantiated. It's possible that notification could happen in a separate thread from the servlet instantiation. You might simply prevent any other listeners from beign notified. The fact that there's no checked exception declared by the method means that other components aren't expecting any exception to be thrown here. You can't really be sure how they'll react. I recommend testing this to see - what happens if you throw an exception here? Be aware, though, that the result you get may depend on your web server. (Or maybe it's well-defined in a spec somewhere; I don't really know.)

In general, yes there are times when there is really no point in proceeding after an exception. And in this cases, it may be a valid option to convert the exception to some kind of RuntimeException, or even Error. But be aware that this may not have the desired effect - try it and see. It may be that the best you can do is log the error, and solve the problem when someone looks at the log.

Another possibility you might consider is to use setAttribute() to set some sort of flag in the context. Then the servlet could later retrieve this in the init() method to understand why it's not working. The init() method can then throw UnavailableException to signal that the servlet was never initialized. In fact, the way you've got it written, you don't need any extra flag. Just check if the applicationProperties attribute is null - if it is, then something went wrong in the listener, before the properties got loaded and put in the context.

Having said that though, why not load the properties in the init() method, rather than the ServletContextListener? That way, you can easily throw the UnavailableException in a place where it's expected, where the container will be able to take appropriate action.

[ January 23, 2008: Message edited by: Jim Yingst ]


Yeah I guess that makes sense. The reason I didn't put it in my init() method is because I have more than one servlet, and all these servlets use the same properties. I'd like to avoid loading properties inside init() as this will lead to duplicate code across servlets, so I thought loading the properties and setting it in the context (where it is global) using a ServletContextListener would enable all servlets to access these properties.

Is this a better approach or does this lead to other problems?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60053
    
  65

The reason I didn't put it in my init() method is because I have more than one servlet, and all these servlets use the same properties.
This is a good reason. With all due respect to Jim, I would under no circumstances put application initialization code into a particular servlet's init() method. That's an artifact of the past before context listeners came onto the scene.
[ January 23, 2008: Message edited by: Bear Bibeault ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Yup, makes sense. I wasn't thinking that though - I was thinking it was just used by one servlet. Silly of course.
Aaron John
Ranch Hand

Joined: May 30, 2005
Posts: 74
Thanks for the suggestions. Here's what I think I'll do. I'll make my ServletContextListener implementation simply log an error if it can't load properties from the property file. Then once it is time for Servlet initialisation, in my init() methods for each of my Servlets, I'll check whether the Properties object is set in the context. If not, then I'll throw an UnavailableException() to the container.

Also in the contextInitialized() method, instead of throwing a RuntimeException, I thought about throwing a MissingResourceException, which is a subclass of RuntimeException. But I think throwing a checked exception is more "correct" in this case.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How should I handle this exception?
 
Similar Threads
If my listener fails to achieve it's tasks...
Property file is cached
Throwing exception from a ServletContextLister Implementation
Servlets and ServletContext
Loading custom application config files