aspose file tools*
The moose likes Web Component Certification (SCWCD/OCPJWCD) and the fly likes RequestDispatcher null? is this possible outcome. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Web Component Certification (SCWCD/OCPJWCD)
Bookmark "RequestDispatcher null? is this possible outcome." Watch "RequestDispatcher null? is this possible outcome." New topic
Author

RequestDispatcher null? is this possible outcome.

Tyler Wright
Ranch Hand

Joined: Jun 25, 2009
Posts: 40
Hi folks,

here is a practice question that has me stumped...



Now, the author gives the following as possible outcomes.
1-start before forward after forward end printed to System.out
2-start end printed to System.out
3-runtime exception at rd.forward(req,res)

1- Ok, I understand that if the resouce "outputText.text" exists and no exceptions are thrown at the forward this is possible and probable.
3- Ok, the forward could throw an exception so yes this is possible.

2- is baffling to me...I can see no reason why rd would ever be null under the conditions present here and if rd is not ever null, then start and end by themselves would not be possible.

I ran this code in Tomcat after changing the name of the '/outputText.text' so that the resource would not exist. Even under this condition System.out printed "start before forward after forward end". While in the browser, the response was that the resouce was not available...and this is what I rather expected.

The only condition I can think of for a null RequestDispatcher being returned is if a RequestDispatcher were requested from a foreign context when the server security policy did not allow cross application interaction...

Am I missing something?

Tyler.

SCJP SCJD
Chinmaya Chowdary
Ranch Hand

Joined: Apr 21, 2008
Posts: 432
Hi, Tyler. What you said is correct. I think option 2 is wrong. I tried this example with little modification in tomcat5.5 like


Here i am not able to get foreign context. I got null for sc2. Can you please explain how to get foreign context? What modification i have to made in tomcat inorder to get foreign context? Thankyou.
Tyler Wright
Ranch Hand

Joined: Jun 25, 2009
Posts: 40
Hi Chinmaya,

I agree with you, I think number 2 is wrong.
This question came from Charles Lyons book (just revised and just now available in US) SCWCD 5 study companion.

What you did to get foreign context servletContext.getContext("/someOtherAppRoot") is absolutely correct; but, tomcat must be configured to allow this.

As far as configuring Tomcat to allow this, I have not explored that yet; but, I know it is possible.
Given what I do know about tomcat, I am sure it is setup in /<apache-tomcat-root>/conf/server.xml but I do not yet know the exact setting.

I am glad though that some else came to the same conclusion that I did about the 2nd answer...it gives me confidence that I am mastering this material.

I hate it when authors give (un-intentionally, I hope) wrong information.

cya,
Tyler
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
I realise this topic is a week old, but hopefully I can still clear it up. The Java EE 5 API documentation for the getRequestDispatcher() method on both javax.servlet.ServletContext and javax.servlet.ServletRequest states:
This method returns null if the servlet container cannot return a RequestDispatcher.
...
Returns: a RequestDispatcher object that acts as a wrapper for the resource at the specified path, or null if the servlet container cannot return a RequestDispatcher

So the container will (or can?) return a null reference if the resource does not exist since the RequestDispatcher cannot be created to forward there. Just so you know I'm not making this up, there is supporting evidence (and more and even more) around for this.

Tyler Wright wrote:I hate it when authors give (un-intentionally, I hope) wrong information.

My apologies if it seems that way. The examples in the book were checked at the original time of writing in 2006 against the then-latest reference implementation and the behaviour was correct then. However, you have to understand that not everything is standardised. Your container could be presenting an error page because it actually does a forward to a non-existent resource, but serves an error page during the Request Dispatching rather than returning null. I would say that's in violation of the specification, but then the spec isn't precise about the meaning of "cannot return a RequestDispatcher".

Edit: Having checked this example against AppServer 9.1 (Glassfish 2), I also obtain a 404 response with a warning in the server logs. It therefore seems the behaviour of this particular container has changed between AppServer 8 used in the 2006 edition of SCWCD Study Companion and Glassfish as recommended in the new 2nd Edition. Just to be more confusing still, if you use ServletContext.getNamedDispatcher("blahblah") where "blahblah" is a non-existent servlet mapping, it will return null rather than present a 404 error. So if you want to avoid potential cross-container issues with NullPointerExceptions being thrown, I would always check for the RequestDispatcher being null.


Charles Lyons (SCJP 1.4, April 2003; SCJP 5, Dec 2006; SCWCD 1.4b, April 2004)
Author of OCEJWCD Study Companion for Oracle Exam 1Z0-899 (ISBN 0955160340 / Amazon Amazon UK )
Tyler Wright
Ranch Hand

Joined: Jun 25, 2009
Posts: 40
Having checked this example against AppServer 9.1 (Glassfish 2), I also obtain a 404 response with a warning in the server logs. It therefore seems the behaviour of this particular container has changed between AppServer 8 used in the 2006 edition of SCWCD Study Companion and Glassfish as recommended in the new 2nd Edition. Just to be more confusing still, if you use ServletContext.getNamedDispatcher("blahblah") where "blahblah" is a non-existent servlet mapping, it will return null rather than present a 404 error. So if you want to avoid potential cross-container issues with NullPointerExceptions being thrown, I would always check for the RequestDispatcher being null.


Charles, what you are saying is that one the 'correct' (answers) possible outcomes for this question is container dependent.







Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
Tyler Wright wrote:Charles, what you are saying is that one the 'correct' (answers) possible outcomes for this question is container dependent.

The more you look into this, the more complicated it can get. So before I give lots of possible angles/interpretations, I'll make two observations:
  • For the purposes of the exam, everything is nice. Given the apparent complexity of this issue, it's highly unlikely they'll test you on what will happen if the resource doesn't exist. So you don't need to worry about this much for the exam.
  • In a production environment, it's important to know how your chosen container and version responds to various stimuli. There is always scope for container-dependent behaviour, features and bugs.

  • Now, the Servlet 3.0 specification states this:
    If no servlet can be resolved based on the given path, a RequestDispatcher is provided that returns the content for that path.

    Again, "returns content for that path" (which doesn't exist remember!) is open to interpretation by the container developers and may depend on how your application is configured. It seems many have chosen to return a 404 response if that is the standard response the container serves when the resource is missing. However, if the container cannot handle the response type or otherwise fails to create a RequestDispatcher, it will return null. The Servlet 3.0 spec also states that it returns null if a servlet mapping does not exist for a call to getNamedDispatcher().

    Naturally, this 404 status code change can only happen if the response has not already been committed, which is fine for a forward (part of the contract), but what happens if it has been committed already when doing an include? I'm not sure that's defined but I guess it would abort page processing and perhaps log an exception? Or maybe not?

    The Servlet 3.0 specification also states:
    The error page mechanism does not intervene when errors occur when invoked using the RequestDispatcher or filter.doFilter method. In this way, a filter or servlet using the RequestDispatcher has the opportunity to handle errors generated.

    This implies to me that custom error pages needn't be displayed for errors relating to RequestDispatching to missing resources... but probably a lot of containers do implement this feature. It also tells me that getRequestDispatcher() should give me some indication the resource doesn't exist so my own servlet can handle the error itself - rather than defaulting to working successfully and displaying a 404 error page (as recent Tomcats, Glassfish et al. do).

    Further, according the API documentation, if a container doesn't support the type of resource you want to forward to or "if the servlet container cannot return a RequestDispatcher", it should return null from all those methods. I don't know who defines or interprets what "cannot return a RequestDispatcher" means precisely. It used to be interpreted as including the scenario where the resource didn't exist, but that seems to have been re-clarified in most recent Servlet specifications.

    AppServer 8 gives the behaviour mentioned in the book's explanation and it is consistent with the API documentation. AppServer 9/Glassfish and Resin (under certain conditions) choose to return a 404 and display an error page (unless using getNamedDispatcher() or they do not support the type of resource) which also seems consistent with the Servlet 3.0 specification. To make matters more complicated (and this could really be a bug), Resin can also throw a FileNotFoundException depending on what type of resource is being forwarded to, and indeed whether it's a forward or an include operation.


    Regarding the question itself, this presents a big difficulty because this behaviour is ill-defined. I'm sure we could argue about which way is better or more correct and still not get to a satisfactory answer! For the sake of the exam, I wouldn't worry too much. I will however make a note of this and may add it into the errata at some point for clarification, or perhaps a small re-write of the question to avoid the ambiguity.
    Charles Lyons
    Author
    Ranch Hand

    Joined: Mar 27, 2003
    Posts: 836
    And to follow up, Glassfish in standard configuration does the following if the target resource does not exist: (1) if you're using a forward(), it returns a 404 error page response; (2) if you're using an include(), it throws a java.io.FileNotFoundException; (3) if you're attempting to obtain a dispatcher via getNamedDispatcher() and it doesn't map to a servlet, it returns null.
    Tyler Wright
    Ranch Hand

    Joined: Jun 25, 2009
    Posts: 40
    Charles,

    I understand that you may be a little sensitive to posts regarding your book's content. That's OK and human.

    What all of this comes down to though, is that the behavior in question is container dependent because the specs are ambiguous (--imagine that!).

    a small re-write of the question to avoid the ambiguity.


    I think you've got it mate!
    Charles Lyons
    Author
    Ranch Hand

    Joined: Mar 27, 2003
    Posts: 836
    I'm thinking that a change to use getNamedDispatcher() instead would be appropriate... I don't use it as commonly, but it would pretty much fix the question and its explanation as-is. I shall add that to the errata when I next have a moment. Thanks for spotting the problem!
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: RequestDispatcher null? is this possible outcome.