jooby-project / jooby

The modular web framework for Java and Kotlin
https://jooby.io
Apache License 2.0
1.71k stars 197 forks source link

Jade engine in RC7 problem with resolving template files #446

Closed marcinc81 closed 8 years ago

marcinc81 commented 8 years ago

Hi, first of all: thank you for the effort and this awesome framework - I hope I will stay with it a bit longer, looks promising!

Today I was struggling with Jade templates because I was getting HTTP 500 error and blank page. Internally it was just null pointer exception when Jade4J was trying to load file using ClasspathTemplateLoader. It couldn't load template file because was outside the "scope" (I think it was the reason). Adding relative or absolute path to template file didn't give any good results. I decided to try other template loaders, so I replaced org.jooby.jade with copied implementation using FileTemplateLoader - and success! Even when template file can't be loaded Jooby sends pretty error message not a blank page.

I think this loader should be replaced - or maybe explained in the Doc how to use it correctly. I must admit that I have no idea how to load jade template using ClasspathTemplateLoader. Also now, when I use FileTemplateLoader I have problem with finding proper templates path - it's relative to target/classes/ - in dev env, in production it can be different path - but I may be wrong here.

jknack commented 8 years ago

Hi,

Sorry you wasted time debugging Jade... something to keep in mind in Jooby is that we usually do configuration/bootstrap of libraries and usually don't wrap, extends or modify external libraries (unless it is absolutely necessary).

What does it means? This sounds like a bug in Jade and their ClasspathTemplateLoader should not returns null. Having said that, would like to know why you got a blank page? Because you shouldn't and Jooby should report with the default error page (not blank).

About, template engine in general:

  1. you usually want to save the templates inside the public directory. The public directory is part of the classpath that is why the Jade module uses the ClasspathTemplateLoader. It is the preferred way and it should work in dev or prod.
  2. Not sure what you mean with:

I replaced org.jooby.jade

Think all you need to do is to save your templates inside public directory and then reference them like:

{
   use(new Jade(".jade"));

   get("/", () -> Results.html("index"));
}

public/index.jade:

doctype html
html
  body
    Hello

Let me know if you have questions and again if you can reproduce the blank page it will be good (makes me worry).

marcinc81 commented 8 years ago

Thanks for reply! It's not time wasting btw, it's a pure pleasure. :)

Answering your questions:

Jooby couldn't render error page due to the same reason - null pointer exception. 1st time exception was thrown due to try loading page template, 2nd time due to loading error template. Both failed (hard).

package com.mycompany;

import org.jooby.Jooby;
import org.jooby.Results;
import org.jooby.jade.Jade;

/**
 * @author jooby generator
 */
public class App extends Jooby {

    {
        use(new Jade(".jade"));
        get("/", () -> Results.html("index"));
    }

    public static void main(final String[] args) throws Throwable {
        run(App::new, args);
    }
}

Blank page is displayed when there's some error, such as 404.

Look at this stack trace:

listening on:
  http://localhost:8080/

[2016-08-11 08:53:15,939]-[netty task-3-1] ERROR org.jooby.Err - execution of: GET/index.jade resulted in exception
Route:
      | Method | Path        | Source      | Name | Pattern     | Consumes | Produces                                                             |
      |--------|-------------|-------------|------|-------------|----------|----------------------------------------------------------------------|
      | GET    | /index.jade | ~unknown:-1 | /err | /index.jade | [*/*]    | [text/html, application/xhtml+xml, application/xml, image/webp, */*] |

Stacktrace:
org.jooby.Err: Not Found(404): /index.jade
        at org.jooby.internal.HttpHandlerImpl.lambda$routes$228(HttpHandlerImpl.java:407) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.RouteImpl.handle(RouteImpl.java:108) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.RouteChain.next(RouteChain.java:70) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.Route$Chain.next(Route.java:2074) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.HttpHandlerImpl.handle(HttpHandlerImpl.java:293) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.netty.NettyHandler.channelRead0(NettyHandler.java:85) [jooby-netty-1.0.0.CR7.jar!/:1.0.0.CR7]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:38) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:363) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:66) [netty-common-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:877) [netty-common-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) [netty-common-4.1.4.Final.jar!/:4.1.4.Final]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_102]
[2016-08-11 08:53:15,960]-[netty task-3-1] ERROR org.jooby.spi.HttpHandler - execution of: GET/index.jade resulted in exception
java.lang.NullPointerException
        at java.io.Reader.<init>(Reader.java:78)
        at java.io.InputStreamReader.<init>(InputStreamReader.java:97)
        at de.neuland.jade4j.template.ClasspathTemplateLoader.getReader(ClasspathTemplateLoader.java:26)
        at de.neuland.jade4j.lexer.Lexer.<init>(Lexer.java:47)
        at de.neuland.jade4j.parser.Parser.<init>(Parser.java:45)
        at de.neuland.jade4j.JadeConfiguration.createTemplate(JadeConfiguration.java:85)
        at de.neuland.jade4j.JadeConfiguration.getTemplate(JadeConfiguration.java:64)
        at org.jooby.jade.Engine.render(Engine.java:46)
        at org.jooby.View$Engine.render(View.java:54)
        at org.jooby.internal.AbstractRendererContext.render(AbstractRendererContext.java:76)
        at org.jooby.internal.ResponseImpl.send(ResponseImpl.java:347)
        at org.jooby.Err$DefHandler.handle(Err.java:72)
        at org.jooby.internal.HttpHandlerImpl.handleErr(HttpHandlerImpl.java:378)
        at org.jooby.internal.HttpHandlerImpl.cleanup(HttpHandlerImpl.java:352)
        at org.jooby.internal.HttpHandlerImpl.handle(HttpHandlerImpl.java:301)
        at org.jooby.internal.netty.NettyHandler.channelRead0(NettyHandler.java:85)
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372)
        at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:38)
        at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:363)
        at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:66)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:877)
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
        at java.lang.Thread.run(Thread.java:745)
Caused by:
org.jooby.Err: Not Found(404): /index.jade
        at org.jooby.internal.HttpHandlerImpl.lambda$routes$228(HttpHandlerImpl.java:407) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.RouteImpl.handle(RouteImpl.java:108) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.RouteChain.next(RouteChain.java:70) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.Route$Chain.next(Route.java:2074) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.HttpHandlerImpl.handle(HttpHandlerImpl.java:293) ~[jooby-1.0.0.CR7.jar!/:1.0.0.CR7]
        at org.jooby.internal.netty.NettyHandler.channelRead0(NettyHandler.java:85) [jooby-netty-1.0.0.CR7.jar!/:1.0.0.CR7]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:38) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:363) [netty-transport-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:66) [netty-common-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:877) [netty-common-4.1.4.Final.jar!/:4.1.4.Final]
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) [netty-common-4.1.4.Final.jar!/:4.1.4.Final]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_102]

Indeed, keeping templates in public folder worked! I added 'err.jade' in /public and now I can see my error page, but without this file: blank page and that stack trace.

Cheers!

jknack commented 8 years ago

Ok, so you found a bug here with Jade! Will fix it! err is required to provide fancy error pages, the default err handler should work here but fails bc expect an IOException and got a NPE :)

If you like jooby don't forget to add a star!!!

Thanks