beard icon indicating copy to clipboard operation
beard copied to clipboard

ClasspathTemplateLoader doesn't resolve paths relative to the root folder

Open Unisay opened this issue 8 years ago • 2 comments

I have the following file structure inside src folder:

.
├── main
│   ├── resources
│   │   ├── logback.xml
│   │   └── templates
│   │       └── index.html
│   └── scala
│       └── org
│           └── zalando
│               └── miadidas
│                   └── customizer
│                       └── Application.scala
├── test
│   ├── resources
│   └── scala

The ClasspathTemplateLoader is setup in the following manner:

val templateLoader = new ClasspathTemplateLoader(
  templatePrefix = "templates/", 
  templateSuffix = ".html")

now when I do

templateCompiler.compile(TemplateName("index"))

I get:

java.lang.IllegalStateException: Could not find template with name TemplateName(index)
	at de.zalando.beard.renderer.CustomizableTemplateCompiler$$anonfun$1.apply(DefaultTemplateCompiler.scala:39)
	at de.zalando.beard.renderer.CustomizableTemplateCompiler$$anonfun$1.apply(DefaultTemplateCompiler.scala:34)
	at scala.util.Try$.apply(Try.scala:192)
	at de.zalando.beard.renderer.CustomizableTemplateCompiler.compile(DefaultTemplateCompiler.scala:33)
	at org.zalando.miadidas.customizer.Application$$anonfun$1.applyOrElse(Application.scala:29)
	at org.zalando.miadidas.customizer.Application$$anonfun$1.applyOrElse(Application.scala:24)
	at org.http4s.package$HttpService$$anonfun$apply$1.apply(package.scala:56)
	at org.http4s.package$HttpService$$anonfun$apply$1.apply(package.scala:56)
	at scalaz.Kleisli$$anonfun$flatMap$1.apply(Kleisli.scala:51)
	at scalaz.Kleisli$$anonfun$flatMap$1.apply(Kleisli.scala:51)
	at org.http4s.server.blaze.Http1ServerStage$$anonfun$runRequest$1.apply(Http1ServerStage.scala:110)
	at org.http4s.server.blaze.Http1ServerStage$$anonfun$runRequest$1.apply(Http1ServerStage.scala:110)
	at scalaz.concurrent.Task$.Try(Task.scala:403)
	at scalaz.concurrent.Task$$anonfun$apply$25.apply(Task.scala:300)
	at scalaz.concurrent.Task$$anonfun$apply$25.apply(Task.scala:300)
	at scalaz.concurrent.Future$$anonfun$apply$15$$anon$4.call(Future.scala:380)
	at scalaz.concurrent.Future$$anonfun$apply$15$$anon$4.call(Future.scala:380)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

The reason for it is that inside ClasspathTemplateLoader there is a code

val path = s"${templatePrefix}${templateName.name}$templateSuffix"
val resource = Option(getClass.getResourceAsStream(path)) // <-- does lookup relative to the `CustomizableTemplateCompiler.class` name

where getClass.getResourceAsStream("templates/index.html") returns null

The fix could be to replace getClass.getResourceAsStream with getClass.getClassLoader.getResourceAsStream (proven in the debugger that latter returns a non-null value)

http://stackoverflow.com/questions/13269556/strange-behavior-of-class-getresource-and-classloader-getresource-in-executa

Unisay avatar Jan 11 '17 14:01 Unisay

Hi @Unisay ,

Have you tried using a leading lash (besides the trailing one you already have) for the templatePrefix param?. Like templatePrefix = "/templates/". Doing so means that the search for the template is done from the resources root directory and then it would work.

tzarouali avatar Feb 21 '17 21:02 tzarouali

I have just stumbled upon the same issue... It would be good to handle it more gracefully...

marcingrabda avatar May 30 '18 03:05 marcingrabda

This repo is now unmaintained and will be archived.

leviferreira avatar Nov 13 '23 14:11 leviferreira