Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileNotFoundException: JAR entry templates/index.gtpl not found in jar #1293

Closed
daggerok opened this issue Nov 12, 2017 · 7 comments
Closed
Milestone

Comments

@daggerok
Copy link

daggerok commented Nov 12, 2017

Hello,

I'm building application using io.ratpack:ratpack-spring-boot:1.5.0

source code for reproduce located here

when I running application using gradle (./gradlew bootRun) or from idea all works fine

http :5050                                                                                                      06:20:59
HTTP/1.1 200 OK
# skipped...

but as if I'm building jar and executing it

./gradlew assemble
java -jar build/libs/*.jar

groovyMarkupTemplate is failing on line 46

          Groovy.groovyMarkupTemplate(model, "index.gtpl", "text/html;charset=UTF-8")

with error: Caused by: java.io.FileNotFoundException: JAR entry templates/index.gtpl not found in /Users/mak/Documents/code/test/ratpack/ratpack-examples/groovy-template-engine/build/libs/groovy-template-engine.jar

full stack trace log:

2017-11-12 06:33:14.739  WARN 62326 --- [ack-compute-1-2] r.e.i.DefaultProductionErrorHandler      : Default production error handler used to render server error, please add a ratpack.error.ServerErrorHandler instance to your application (method: GET, uri: /)


ratpack.render.RendererException: Renderer 'ratpack.groovy.template.internal.MarkupTemplateRenderer@3b1d6970' failed to render 'ratpack.groovy.template.MarkupTemplate@3adc3627'
        at ratpack.render.internal.DefaultRenderController.doRender(DefaultRenderController.java:74) ~[ratpack-core-1.5.0.jar!/:na]
        at ratpack.render.internal.DefaultRenderController.doRender(DefaultRenderController.java:59) ~[ratpack-core-1.5.0.jar!/:na]
        at ratpack.render.internal.DefaultRenderController.render(DefaultRenderController.java:40) ~[ratpack-core-1.5.0.jar!/:na]
        at ratpack.handling.internal.DefaultContext.render(DefaultContext.java:236) ~[ratpack-core-1.5.0.jar!/:na]
        at daggerok.ratpack.RatpackConfig.lambda$null$1(RatpackConfig.java:45) [classes!/:na]
        at ratpack.exec.internal.DefaultPromise$1.success(DefaultPromise.java:45) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.Downstream.accept(Downstream.java:180) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.Blocking.lambda$null$0(Blocking.java:84) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.internal.DefaultExecution$SingleEventExecStream.exec(DefaultExecution.java:430) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.internal.DefaultExecution.exec(DefaultExecution.java:196) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.internal.DefaultExecution.intercept(DefaultExecution.java:189) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.internal.DefaultExecution.drain(DefaultExecution.java:169) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.internal.DefaultExecution.access$600(DefaultExecution.java:42) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.internal.DefaultExecution$SingleEventExecStream.doResume(DefaultExecution.java:497) ~[ratpack-exec-1.5.0.jar!/:na]
        at ratpack.exec.internal.DefaultExecution$SingleEventExecStream.lambda$resume$0(DefaultExecution.java:490) ~[ratpack-exec-1.5.0.jar!/:na]
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) ~[netty-common-4.1.9.Final.jar!/:4.1.9.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403) ~[netty-common-4.1.9.Final.jar!/:4.1.9.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442) ~[netty-transport-4.1.9.Final.jar!/:4.1.9.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) ~[netty-common-4.1.9.Final.jar!/:4.1.9.Final]
        at ratpack.exec.internal.DefaultExecController$ExecControllerBindingThreadFactory.lambda$newThread$0(DefaultExecController.java:136) ~[ratpack-exec-1.5.0.jar!/:na]
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) ~[netty-common-4.1.9.Final.jar!/:4.1.9.Final]
        at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_152]
Caused by: java.lang.RuntimeException: Impossible to read the text content from jar:file:///Users/mak/Documents/code/test/ratpack/ratpack-examples/groovy-template-engine/build/libs/groovy-template-engine.jar!/templates/index.gtpl
        at groovy.lang.GroovyCodeSource.<init>(GroovyCodeSource.java:187) ~[groovy-all-2.4.12.jar!/:2.4.12]
        at groovy.text.markup.MarkupTemplateEngine$MarkupTemplateMaker.<init>(MarkupTemplateEngine.java:218) ~[groovy-all-2.4.12.jar!/:2.4.12]
        at groovy.text.markup.MarkupTemplateEngine.createTemplateByPath(MarkupTemplateEngine.java:145) ~[groovy-all-2.4.12.jar!/:2.4.12]
        at ratpack.groovy.template.internal.MarkupTemplateRenderer.render(MarkupTemplateRenderer.java:54) ~[ratpack-groovy-1.5.0.jar!/:na]
        at ratpack.groovy.template.internal.MarkupTemplateRenderer.render(MarkupTemplateRenderer.java:37) ~[ratpack-groovy-1.5.0.jar!/:na]
        at ratpack.render.internal.DefaultRenderController.doRender(DefaultRenderController.java:69) ~[ratpack-core-1.5.0.jar!/:na]
        ... 21 common frames omitted
Caused by: java.io.FileNotFoundException: JAR entry templates/index.gtpl not found in /Users/mak/Documents/code/test/ratpack/ratpack-examples/groovy-template-engine/build/libs/groovy-template-engine.jar
        at org.springframework.boot.loader.jar.JarURLConnection.throwFileNotFound(JarURLConnection.java:186) ~[groovy-template-engine.jar:na]
        at org.springframework.boot.loader.jar.JarURLConnection.connect(JarURLConnection.java:105) ~[groovy-template-engine.jar:na]
        at org.springframework.boot.loader.jar.JarURLConnection.getInputStream(JarURLConnection.java:170) ~[groovy-template-engine.jar:na]
        at org.codehaus.groovy.runtime.ResourceGroovyMethods.configuredInputStream(ResourceGroovyMethods.java:2021) ~[groovy-all-2.4.12.jar!/:2.4.12]
        at org.codehaus.groovy.runtime.ResourceGroovyMethods.newReader(ResourceGroovyMethods.java:2107) ~[groovy-all-2.4.12.jar!/:2.4.12]
        at org.codehaus.groovy.runtime.ResourceGroovyMethods.getText(ResourceGroovyMethods.java:649) ~[groovy-all-2.4.12.jar!/:2.4.12]
        at org.codehaus.groovy.runtime.ResourceGroovyMethods.getText(ResourceGroovyMethods.java:612) ~[groovy-all-2.4.12.jar!/:2.4.12]
        at groovy.lang.GroovyCodeSource.<init>(GroovyCodeSource.java:184) ~[groovy-all-2.4.12.jar!/:2.4.12]
        ... 26 common frames omitted

I've checked bundled jar and index.gtpl exists

cd build/libs/
unzip -l ./groovy-template-engine.jar | grep index.gtpl
      363  11-12-2017 06:27   BOOT-INF/classes/templates/index.gtpl

so it should be available in runtime by path template/index.gtpl

note: spring mvc in all cases renders template successfully (http :8080)


Regards,
Maksim

@daggerok
Copy link
Author

daggerok commented Nov 12, 2017

Seems like issue doesn't depends on ratpack, I face with very same problem here

But anyway, I would be glad, If anybody previously solve this problem and can share

--
Best regards,
Max

@daggerok
Copy link
Author

daggerok commented Nov 14, 2017

Hello,

I have quick update, regarding posted issue: seems like resources should be loaded using input stream. with spring context I can inject ResourceLoader via constructor and read tile content like so:

    val resource = resources.getResource("classpath:templates/index.gtpl")

    InputStreamReader(resource.inputStream).use {
      return it.readText()
    }

but I cannot use it with ratpack.groovy.Groovy.groovyMarkupTemplate - that method expects the id/name of the template, not content...

I debug a little bit more and found that application fails on resolveTemplate - maybe it's ok for files from file system, but not for files from jar? at this moment templatesDir is pointing as absolute path to templates dir, so it couldn't be resolved in jar

@SlyDen
Copy link
Contributor

SlyDen commented Nov 14, 2017

there is your *.tpl file in the project (relative path) and your .ratpack file (which is effectively a marker for ratpack to find a baseDir and find the resources relatively to it) ??

@daggerok
Copy link
Author

daggerok commented Nov 14, 2017

hello, @SlyDen

.ratpack file is inside src/main/resources folder

*.gtpl files are inside src/main/resources/templates folder

instead of .tpl im's using .gtpl, but It shouldn't be an issue as far I'm explicitly telling Groovy.groovyMarkupTemplate a name, (not id):

      Blocking.get(() -> {
        final HashMap<String, Object> model = new HashMap<String, Object>();
        model.put("message", "This is a groovy template engine from ratpack!");
        model.put("users", userRepository.findAll()
                                         .stream()
                                         .map(User::toString)
                                         .collect(toList()));
        return model;
      }).then(model -> context.render(
          Groovy.groovyMarkupTemplate(model, "index.gtpl", "text/html;charset=UTF-8")
      ));

in my previous post I mentioned that in another spring-boot project I faced with very same problem when I've tried get resource like it can be done from regular file system and this isn't work with jar, so I think Groovy.groovyMarkupTemplate in this case is doing same, that is why it's working with filesystem resources, but not with resources from bundled jar file

note 1

jar execution also won't work even if I copied templates folder and .ratpack file in current directory:

gradle build
cp -Rf src/main/resources/templates ./
cp src/main/resources/.ratpack ./
java -jar build/libs/groovy-template-engine.jar
http :5050 # response 500

note 2

and again, with gradle bootRun command or idea run configurations all works fine, but not with executable jar command: java -jar build/libs/groovy-template-engine.jar


Regards,
Maksim

@ldaley
Copy link
Member

ldaley commented Jan 9, 2018

Hi @daggerok

I've spent a little time looking at this. The problem is clearly in org.springframework.boot.loader.jar.JarURLConnection. For some reason, it doesn't think that templates/index.gtpl is in the JAR when it clearly is.

I don't think there's anything Ratpack can do here. As such, I'm going to close this issue.

@ldaley ldaley closed this as completed Jan 9, 2018
@ldaley ldaley added this to the none milestone Jan 9, 2018
@daggerok
Copy link
Author

daggerok commented Jan 10, 2018

Hello @ldaley,

I was facing with similar issues previously (it depends on class loader), and all the time I was able fix it by lookup file resources using right class loader. With current API i can't apply such fix.

Does anybody knows something similar for Groovy.groovyMarkupTemplate? Something like

resource = getClass().getClassLoader().getResourceAsStream("index.gtpl")...
Groovy.groovyMarkupTemplate(model, resource);

I don't think there's anything Ratpack can do here. As such, I'm going to close this issue.

it definitely can, because I'm using ratpack API for:

import ratpack.groovy.Groovy;
import ratpack.groovy.template.MarkupTemplateModule;

I think it shouldn't be very hard add method with such functionality which takes resource from classloader and after (during render processing) will able find file in jar. All problem is accessng to file from jar, otherwise it work f wine if application is unbundled..


Regards

@ldaley
Copy link
Member

ldaley commented Jan 10, 2018

The better fix would be for the Spring Boot team to fix their custom JAR URL loader to find the file that is there. Then this would just work.

If you would like to submit a patch to have the MarkupTemplate in Ratpack be optionally backed by a string instead of relying on pointing something to the file system, that would be a nice improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants