I am working on a web application using the Spring framework and Hibernate. My problem is that I often receive 404 errors caused by a mistake I have made somewhere in the codebase but there are no exception messages in the console. Because of this I am struggling to find where the mistake is because the project has become very large and manually trying to find the problem is impractical. I'm assuming that Spring is causing the problem so my question is: is there some way of enabling more detailed error messages? Thanks
404 is an http error and only your web server might be knowing of it. Very likely with these failed requests, your application server or Spring container was never hit. Look for web server logs to identify the problem.
Troubleshooting 404 on IIS server
http://blogs.iis.net/tomkmvp/archive/2009/04/27/troubleshooting-a-404.aspx
Troubleshooting 404 on RAD web server
http://www-304.ibm.com/support/docview.wss?uid=swg27035752&aid=1
As a couple of people have already alluded to it, the issue here is that certain errors (like the 404 exception) get intercepted by the Servlet container, therefore never reaching Spring and whatever logging mechanisms you have may have set up. So the trick here is to change the order of importance of your Exceptions so that Spring gets a crack at it.
The best approach I have ever come across to catch, handle and adequately log all exceptions in Spring is described in this article: http://steveliles.github.io/configuring_global_exception_handling_in_spring_mvc.html
I have been implementing this setup since I came across that blog post, and it has been a lifesaver to say the least. It will give you the detailed error messages you need. The key is to basically create a custom Exception Handler by implementing Spring's HandlerExceptionResolver and Ordered interfaces, then returning the lowest possible order number, thus moving your exception handling up the totem pole:
import org.springframework.core.*;
import org.springframework.web.servlet.*
public class LoggingHandlerExceptionResolver
implements HandlerExceptionResolver, Ordered {
public int getOrder() {
return Integer.MIN_VALUE; // we're first in line, yay!
}
public ModelAndView resolveException(
HttpServletRequest aReq, HttpServletResponse aRes,
Object aHandler, Exception anExc
) {
anExc.printStackTrace(); // again, you can do better than this ;)
return null; // trigger other HandlerExceptionResolver's
}
}
The problem ended up being that there were a couple of missing annotations from one of my Hibernate entities. Following the procedure from the link below helped track it down by providing more detailed error messages:
http://www.captaindebug.com/2011/07/using-hibernate-validation-annotation.html
I also hit the problem of no console output while 404 error.
As in The Saint's answer, one of the causes of no console log:
the issue here is that certain errors (like the 404 exception) get intercepted by the Servlet container
"spring-framework-reference-3.2.3.pdf" --> 1.3 --> Logging --> Using Log4J, solved the problem in my environment.
Related
I have a pretty big project with a lot of different controllers. I do have a main controller that has all of the mappings for the start of the program like (/login, /resetPassword, /logout, etc). I also do not have a web.xml file in the project. I need to add a custom error page for all unmapped requests. I have tried creating my own exception class and didn't work. Most of the solutions I find are to add error location to the web.xml. I would prefer not to have to create one but if anybody has any tips or can push me in the right direction that would help out so much. I've been stuck on this problem for a couple of days now. Thanks.
You should use 404 mapped to an error page in web.xml. Because it will handle even url requests that are not mapped to your DispatcherServlet. For example, imagine your Spring DispatcherServlet is mapped to any url ending in .htm, now some mistypes and tried to access something/somethingelse.do your application server will now present its own default error page to the user, which might not be pleasant.
The only time you should think about serving custom error pages from your MVC controllers, is when you have something specific to show the user. Specific as in, if an exception is encountered in this particular controller, I want to show a specific message, or redirect the user to a specific page. In these cases, you can use #ExceptionHandler methods in Spring controllers.
For more, look at this blog post, or refer the MVC documentation: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
See this answer: How to make a filter to detect if the user requested a page that is not found?
Make a Filter
Use HttpServletResponseWrapper and override the sendError() and setStatus()
Pass the wrapped response through chain.doFilter(req, wrapper)
If you get a sendError() in your wrapper, see if it's a 404.
Take appropriate response.
I am working on Spring3.0, Hibernate 3.2 web application deployed on JBOSS 4.3.
It's live product and getting this exception, when 30k users are utilizing it.
Exception : level=ERROR class=org.directwebremoting.dwrp.DefaultConverterManager No converter found for 'java.lang.StackTraceElement'
Its not generating much log as well and not able to find the same exception on internet.Anybody can tell me or any clue about it.
Why it's coming in production only not in local dev environment.
How much impact can be done of this exception on the system ?
Seems the application generates exceptions under load and tries to send back stack traces from them to the client. DWR is then unable to serialize the stack trace elements.
See here and here for possible DWR configurations that could solve the problem.
We have a service based platform where its possible (/common) for a resource not to be found - e.g. calling our security module with the wrong username will return 404 Not Found, something that will happen every time a user makes a typo in their login box.
We use Spring RestTemplate for these calls, which is great, but every time a 404 is encountered it dutifully logs a warning which is spamming our logs.
We obviously don't want to suppress warnings, except in the specific case of 404 not found but there doesn't appear to be a way to do this (logger is private/final, method to invoke it is private etc).
Our solution is not good - to return 200/OK with empty dataset and handle a null pointer, which is both nasty and not a good restful implementation.
Does anyone know a better way to do this?
How about using a RegexFilter filter on your logging appender?
http://logging.apache.org/log4j/2.x/manual/filters.html#RegexFilter
... that's the Log4J way of doing it, but I'm guessing there must be similar filters for other logging libraries.
Implement a ResponseErrorHandler that returns false for hasError().
Assign it to your rest template using setErrorHandler().
The warning will not be logged.
This was logged in as issue SPR-12760 in the issue tracker of Spring Framework and resolved earlier this year (2015) in version 4.1.6. The solution was twofold: first, the warning message was downgraded to a debug message, and second, it was made easier to override the part of the code that is responsible for handling errors. So as a solution to your problem, upgrade the org.springframework:spring-web module to at least version 4.1.6.RELEASE.
I am having trouble getting requests routed to one of my Spring #Controller that use #RequestMapping it is usually caused by a typo on my part but it is still annoying to hunt down those typos when you have a lot of controllers like I do.
for example a URI like /abc/{id}/something/{anotherId}
Is there some way to get spring to print out the process it used to determine that there was no match? In particular what would be useful is to know how far down the URI path there was a match as that would make finding typos a lot easier.
What debug flags exist for troubleshooting routing problems?
There are a few things that you can do -
Increase the log level - to DEBUG or may be even TRACE, this will clearly show how Spring MVC is trying to match your request to a handler method.
Debug - you can put a breakpoint as early as the DispatcherServlet and see how the mapping is being resolved.
You can implement a Endpoint Documentation Controller - something along these lines - http://biju-allandsundry.blogspot.com/2012/03/endpoint-documentation-controller-for.html, which can show all the endpoints URI's supported in the application.
My webapp is part of a larger EAR that is deployed into a websphere server. The server hosts number of other apps on the same virtual server. My webapp has some initialisation/health checks in a servletContextListener->contextInitialized method. I want to make the webapp unavailable if initialisation/health checks fail. What is a realiable way of doing this? Will throwing a RuntimeException from within contextInitialized suffice? Is the rest of the EAR still expected to be available? Thank you.
I'd recommend throwing a RuntimeException from ServletContextListener.contextInitialized.
Servlet 2.3 wasn't very clear on this, but Servlet 2.4 added the following detail:
Some exceptions do not occur under the
call stack of another component in the
application. An example of this is a
… ServletContextListener that
throws an unhandled exception during a
notification of servlet context
initialization…. In this case,
the Developer has no opportunity to
handle the exception. The container
may respond to all subsequent requests
to the Web application with an HTTP
status code 500 to indicate an
application error.
Since it says that the servlet engine "may" disable access to application, you might find a server that does something else. However, Tomcat and WebLogic both disable the application, and the only other reasonable thing I can think of would be to ignore the exception. I can't see a container that did that being very popular—so you'd better test it in WebSphere yourself.
Throwing a RuntimeException will probably make only that servlet unavailable. A safer way might be to implement something like a Spring interceptor that will forward to an error page or something if the checks didn't pan out. That way, you don't need to prevent the app from loading, but can handle it more gracefully at run time.