Can't load page with precompile code and remove sources.
Framework version: 1.2
Platform you're using: Windows
1. first precompile the code by execute: play precompile.
2. and then remove the app directory: rm -rf app(or mv app app.bak).
3. start the app with precompiled option: play run -Dprecompiled=true
4. open http://localhost:9000, and oops.
It throw exception:
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:227) at Invocation.HTTP Request(Play!)
Caused by: java.lang.NullPointerException
at play.exceptions.TemplateNotFoundException.<init>(TemplateNotFoundException.java:25) at play.mvc.Controller.renderTemplate(Controller.java:664) at play.mvc.Controller.renderTemplate(Controller.java:637) at play.mvc.Controller.render(Controller.java:692) at controllers.Application.index(Application.java:13) at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:540) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:498) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:474) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:469) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:157) ... 1 more
Comments and changes to this ticket
- Tag set to precompiled, template
I've been looking at this and found the following. The codebase I'm referencing is 1.2.3.
TemplateLoader.load(VirtualFile file) on line 58 includes logic to load templates from the precompiled folder. However, it is called from TemplateLoader.load(String path) on line 164. This latter method does a check to see if the template named by the path is present in the virtual filesystem and only calls the former method if it is. Of course, when running precompiled with the source folder completely removed, this check fails and throws the TemplateNotFoundException.
TemplateLoader.load(String path) needs to take account of the Play.usePrecompiled flag to deal with this situation. Alternatively, Play.init could be updated to add the precompiled/templates/app/views directory to the templatesPath list when usePrecompiled is set to true.
Hmm, actually the change to Play.init is not quite sufficient as BaseTemplate add "precompiled/templates" to the front of the filename when loading precompiled. Just adding "precompiled/templates" to the template path thus results in BaseTemplate attempting to find a file that starts "precompiled/templates/precompiled/templates".
Looks like the correct fix will lie in TemplateLoader.load(String path) after all where it will need to take into account the Play.usePrecompiled flag.
And a few more hours' of tinkering, and I think I've found a solution that minimises the changes to the source. All the changes are in TemplateLoader.java. It's a slight hack, but will let Play run in precompiled mode without an app/views directory in the application root.
I've pushed the fix onto the 1.2.x branch of my fork (wiredthing/play.git) and issued a pull request (https://github.com/playframework/play/pull/391) if you feel like incorporating the change. This is the first time I've contributed to this project so if I've got any of the process wrong please let me know.
The workaround isn't really a workaround, though. You still have to deploy the template sources, even though you can leave out the java sources, so it's not really running without the sources, is it? The Play code is attempting to make this work, but gets it wrong. I'm not sure why you don't want to incorporate the fix?
I'd suggest that you should at least update the play documentation to make it clear that you need to keep the template sources around so that people don't spend a lot of time working this out for themselves in the future.
I made it as small as I could to fix the problem :-)
Actually, there are two fixes in the branch. Commit a46cdf8cc2254a893ff45b686c9d0ad14e9c4874 (with a comment starting [#806]) fixes the problem with a very small amount of change and no API changes, but is not very clean. The 2ad255afe2d65c8a17ae363d4b00814c962bbc17 commit is much more extensive and, as you say, changes the API.
So maybe just merge a46cdf8cc2254a893ff45b686c9d0ad14e9c4874? If I can help by presenting the pull request in a different way then please let me know.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
Play makes it easier to build Web applications with Java. It is a clean alternative to bloated Enterprise Java stacks. It focuses on developer productivity and targets RESTful architectures. Learn more on the <a href="http://www.playframework.org">http://www.playframework.org</a> website.<br><br>
<h2>Source code is hosted on github</h2>Check out our repository at <a href="http://github.com/playframework/play">http://github.com/playframework/play</a><br><br>
<h2>Contributing, creating a patch</h2> Please read the <a href="http://play.lighthouseapp.com/projects/57987/contributor-guide">contributor guide</a><br><br>
<h2>Reporting Security Vulnerabilities</h2> Since all bug reports are public, please report any security vulnerability directly to <em>guillaume dot bort at gmail dot com</em>.<br><br>
<h2>Creating a bug report</h2> Bug reports are incredibly helpful, so take time to report bugs and request features in our ticket tracker. We’re always grateful for patches to Play’s code. Indeed, bug reports with attached patches will get fixed far quickly than those without any.<br><br>
Please include as much relevant information as possible including the exact framework version you're using and a code snippet that reproduces the problem.<br><br>
Don't have too much expectations. Unless the bug is really a serious "everything is broken" thing, you're creating a ticket to start a discussion. Having a patch (or a branch on Github we can pull from) is better, but then again we'll only pull high quality branches that make sense to be in the core of Play.