question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`Failed to init template entry.kte, no method named 'render' found in class gg.jte.generated.precompiled.JteentryGenerated` when argument is Kotlin value class

See original GitHub issue

Hello,

I use jte 2.1.1 inside my ktor application with Gradle. Gradle setup is following:

jte {
    generate()
    sourceDirectory.set(Paths.get("templates"))
    contentType.set(gg.jte.ContentType.Html)
    binaryStaticContent.set(true)
    trimControlStructures.set(true)
}

Most part of templates work fine, but for one of them, namely entry.kte seemingly there is no “render” method. At least during debug I can’t find it too. Here’s the entry.kte content:

@import io.github.asm0dey.plugins.*
@import java.time.*

@param content: String
@param summary: String
@param book: BookWithInfo
@param imageType: String
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:dcterms="http://purl.org/dc/terms/">
    <title>${book.book.name}</title>
    <id>/opds/book/${book.id}/info</id>
    @for(author in book.authors)
    <author>
        <name>${author.buildName()}</name>
        <uri>/opds/author/browse/${author.id}</uri>
    </author>
    @endfor
    <published>${formatDate(ZonedDateTime.now())}</published>
    <updated>${formatDate(book.book.added)}</updated>
    @if(book.book.lang != null)
    <dcterms:language>${book.book.lang}</dcterms:language>
    @endif
    @if(book.book.date != null)
    <dcterms:date>${book.book.date}</dcterms:date>
    @endif
    @for(genre in book.genres)
    <category term="${genre}" label="${genre}"/>
    @endfor
    @if(imageType != null)
    <link type="${imageType}" rel="http://opds-spec.org/image" href="/opds/image/${book.id}"/>
    @endif
    <link type="application/fb2+zip" rel="http://opds-spec.org/acquisition/open-access" href="/opds/book/${book.id}/download"/>
    @if(summary != null)
    <summary type="text">${summary}</summary>
    <content type="html">$unsafe{content}</content>
    @endif
</entry>

Looking at javap output I can see following:

❯ javap ./build/classes/kotlin/main/gg/jte/generated/precompiled/JteentryGenerated.class | grep render
  public static final void render-JMhnnco(gg.jte.html.HtmlTemplateOutput, gg.jte.html.HtmlInterceptor, java.lang.String, java.lang.String, org.jooq.Record4<java.lang.Long, java.util.List<? extends io.github.asm0dey.opdsko.jooq.tables.pojos.Book>, java.util.List<? extends io.github.asm0dey.opdsko.jooq.tables.pojos.Author>, java.util.List<? extends java.lang.String>>, java.lang.String);
  public static final void renderMap(gg.jte.html.HtmlTemplateOutput, gg.jte.html.HtmlInterceptor, java.util.Map<java.lang.String, ? extends java.lang.Object>);

Further investigation:

BookWithInfo is a value class:

@JvmInline
value class BookWithInfo(private val record: Record4<Long, List<BookPojo>, List<Author>, List<String>>) {
    val book get() = record.component2()[0]
    val authors get() = record.component3()!!
    val genres get() = record.component4().map { genreNames[it] ?: it }
    val id get() = record.get(BOOK.ID)!!
}

Maybe this is the reason why we can see a bridge-like render-JMhnnco method in the JteentryGenerated.class?

However, for other template, where BookWithInfo participates too, but in a List, not by itself, everything is being generated fine:

❯ javap ./build/classes/kotlin/main/gg/jte/generated/precompiled/JtebooksGenerated.class | grep render
  public static final void render(gg.jte.html.HtmlTemplateOutput, gg.jte.html.HtmlInterceptor, java.util.List<io.github.asm0dey.plugins.BookWithInfo>, java.util.Map<java.lang.Long, java.lang.String>, java.util.Map<java.lang.Long, java.lang.String>, java.lang.String, java.lang.String, java.lang.String, java.time.temporal.TemporalAccessor, java.util.List<io.github.asm0dey.model.Entry$Link>);
  public static final void renderMap(gg.jte.html.HtmlTemplateOutput, gg.jte.html.HtmlInterceptor, java.util.Map<java.lang.String, ? extends java.lang.Object>);

Maybe this is an error on Kotlin compiler’s side, but it appears to me that template detection method should be just a bit more sophisticated and be aware that Kotlin value classes exist as well as such bridge methods.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:17 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
asm0deycommented, Jul 3, 2022

Me too! Thank you for help with investigation and effort to fix!

вс, 3 июл. 2022 г., 12:44 Andreas Hager @.***>:

Seemingly it works! You can find the build here: https://jitpack.io/#casid/jte/fa73ea1a9d (I hate mvn install when I have other options 😃

Oh, that’s really convenient, thanks for sharing this trick!

Thank you for testing & confirming the fix. I’m glad we got it working 😃

— Reply to this email directly, view it on GitHub https://github.com/casid/jte/issues/163#issuecomment-1173048337, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJ4XATOFHRDCKKSGLMIMPTVSFOHZANCNFSM5Z3RP3JQ . You are receiving this because you were mentioned.Message ID: @.***>

1reaction
asm0deycommented, Jul 3, 2022

Generated bytecode includes

  public static final void render-JMhnnco(gg.jte.html.HtmlTemplateOutput, gg.jte.html.HtmlInterceptor, java.lang.String, java.lang.String, org.jooq.Record4<java.lang.Long, java.util.List<? extends io.github.asm0dey.opdsko.jooq.tables.pojos.Book>, java.util.List<? extends io.github.asm0dey.opdsko.jooq.tables.pojos.Author>, java.util.List<? extends java.lang.String>>, java.lang.String);
Read more comments on GitHub >

github_iconTop Results From Across the Web

Using kotlin data classes in jte templates have issues ... - GitHub
doesn't add to srcDirs, but replaces them? I tried to find a kotlin version of sourceSets.main.java.srcDirs += tasks.generateJte.targetDirectory ...
Read more >
Rendering jte templates in Javalin
TemplateException : Failed to compile template, error at hello.jte:2 /Users/casid/javalin/javalin/jte-classes/gg/jte/generated/JtehelloGenerated.
Read more >
Java compile exception with kotlin(ReifiedParameterizedType ...
I have error when try compile my java code with kotlin dependencies: org.springframework.beans.factory.BeanCreationException: Error creating ...
Read more >
Micronaut Views - GitHub Pages
Your controller's method can render the response with a template by using the View annotation. The following is an example of a controller...
Read more >
JTE - Ktor
Ktor allows you to use JTE templates as views within your application by installing the Jte plugin. Add dependencies. To use Jte ,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found