4

I discovered Guice last week... I'm trying some easy tricks with it. However, I'm currently blocked...

I'm trying to forward a request to a JSP in a Servlet served by an url-pattern which contains a " * ". But I receive "Error 404" all the time :(

Step by Step :


ServletModule :
serve("/test/*").with(TestServlet.class);

TestServlet :
public void doGet(HttpServletRequest req, HttpServletResponse resp)  
{

    System.err.println("Start");
    try 
    {
        req.getRequestDispatcher("/WEB-INF/layout/test.jsp").forward(req, resp);
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }

}

I get this error :

HTTP ERROR 404
Problem accessing /WEB-INF/layout/test.jsp. Reason:
/WEB-INF/layout/test.jsp

I tested with "serve("/test").with(TestServlet.class);" and it worked
I tested without Guice (by defining servlet in the web.xml) and it worked...

  • What did I do wrong?

Thank for reading!

Stan Kurilin
  • 15,614
  • 21
  • 81
  • 132
Pierre
  • 139
  • 3
  • 8
  • Than try use `include` instead of `forward`) – Stan Kurilin Mar 12 '11 at 18:01
  • @Stas: it sounds like you're just suggesting random guesses. – Matt Ball Mar 12 '11 at 18:02
  • 1
    I don't do Guice, but this error page is suggesting that the request is been redirected to the JSP instead of being forwarded by `RequestDispatcher`. The `/WEB-INF` folder is indeed not public accessible as @Matt mentions. Do you see the URL in the browser address bar being changed to one with `/WEB-INF` inside? If so, then a redirect has been taken place somehow. – BalusC Mar 12 '11 at 18:03
  • @Matt Ball, correct. So it is not answer. Just comment. I'll delete wrong suggestions. – Stan Kurilin Mar 12 '11 at 18:04
  • I got : http://localhost:8888/test/74854 in my address bar -- @Stas Kurilin include works ! Why forward didn't work? – Pierre Mar 12 '11 at 18:27

3 Answers3

8

Client can't access resources from Web-INF directly (by url). So forwarding doesn't work in this case. But your servlets can. So just use include instead of forward.

Stan Kurilin
  • 15,614
  • 21
  • 81
  • 132
6

There's a good chance you didn't do anything wrong at all. There is a bug in Guice, arising from their mishandling of Include and Forward attributes against servlet standards, as described here... http://code.google.com/p/google-guice/issues/detail?id=647

The upshot is that the receiving servlet is misinformed about the path, and hence requests to load resources do not find their proper target even if they are specified correctly and even if the same code works when using web.xml (which is interpreted by your servlet engine and not by Guice).

I'm endlessly puzzled why this doesn't act as a dead-end for many many projects in Guice, so perhaps there's something in the behaviour of other servlet engine configurations which masks this error. I'm using Jetty launched explicitly in Java using Server#start(); and it is a deal-breaker for a lot of server logic.

However, the Guice team seems to have been studiously ignoring the bug for a long time, even when a patch was provided to them against v2.0. What they need is a test-case written against their SVN build but I've never succeeded given all the work needed to create stubs which emulate the servlet engine and so on.

Cefn Hoile
  • 61
  • 1
  • 1
4

The problem has been partially fixed in guice and guice servlet 3.1.1 with one problem still taking place:

When mapping a servlet using the asterisk pattern '/*' as below:

serve("/myservlet/*").with(MyServlet.class);

And have MyServlet.java forward to a jsp page, then the forward() will only work if the jsp page has no underscores (So, myservlet.jsp will work, my_servlet.jsp wont work).

// This WORKS
req.getRequestDispatcher("/myservlet.jsp").forward(req,resp);

// These DONT WORK (any file having _ or - characetsrs wont work)
req.getRequestDispatcher("/my_servlet.jsp").forward(req,resp); 
req.getRequestDispatcher("/my-servlet.jsp").forward(req,resp); 
req.getRequestDispatcher("/WEB-INF/myservlet.jsp").forward(req,resp);

Now this explains why WEB-INF forwarding does not work for a servlet mapped with /*. The reason is that WEB-INF contains a dash character which for some reason is creating a problem for guice servlet. When trying the example above, make sure to rename the file myservlet.jsp to my_servlet.jsp when trying the cases to verify the case above.

I have no idea why this weird case is taking place. NOTE: I'm using Tomcat 6.0.35

To have Guice 3.1.1 add these to your pom.xml

    <dependency>
        <groupId>org.sonatype.sisu</groupId>
        <artifactId>sisu-guice</artifactId>
        <version>3.1.1</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.sonatype.sisu.inject</groupId>
        <artifactId>guice-servlet</artifactId>
        <version>3.1.1</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.sonatype.sisu.inject</groupId>
        <artifactId>guice-assistedinject</artifactId>
        <version>3.1.1</version>
        <scope>compile</scope>
    </dependency>

Or you can download the jars from:

Guice Servlet Jar

http://repo1.maven.org/maven2/org/sonatype/sisu/inject/guice-servlet/3.1.1/

Guice Jar

http://repo1.maven.org/maven2/org/sonatype/sisu/sisu-guice/3.1.1/

Basil Musa
  • 8,198
  • 6
  • 64
  • 63