casid / jte

Secure and speedy templates for Java and Kotlin.
https://jte.gg
Apache License 2.0
748 stars 56 forks source link

ContentType.Plain trying to render documents HtmlTemplateOutput #281

Closed venkatwilliams closed 11 months ago

venkatwilliams commented 11 months ago

this.templateEngine = TemplateEngine.createPrecompiled(ContentType.Plain); Getting the following error:

java.lang.RuntimeException: gg.jte.TemplateException: Failed to render documents.jte] with root cause

java.lang.IllegalArgumentException: argument type mismatch
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at gg.jte.runtime.Template.renderMap(Template.java:58) ~[jte-runtime-3.1.1.jar:na]
        at gg.jte.TemplateEngine.render(TemplateEngine.java:230) ~[jte-runtime-3.1.1.jar:na]

documents.jte

@param String document1
@param String document2
DOCUMENT 1:
${document1}

DOCUMENT 2:
${document2}

GeneratedClass:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package gg.jte.generated.ondemand;

import gg.jte.html.HtmlInterceptor;
import gg.jte.html.HtmlTemplateOutput;
import java.util.Map;

public final class JtedocumentsGenerated {
  public static final String JTE_NAME = "documents.jte";
  public static final int[] JTE_LINE_INFO = new int[]{0, 0, 0, 0, 3, 3, 3, 3, 6, 6, 6, 7};

  public JtedocumentsGenerated() {
  }

  public static void render(HtmlTemplateOutput jteOutput, HtmlInterceptor jteHtmlInterceptor, String document1, String document2) {
    var0.writeContent("DOCUMENT 1:\n");
    var0.setContext("html", (String)null);
    var0.writeUserContent(var2);
    var0.writeContent("\n\nDOCUMENT 2:\n");
    var0.setContext("html", (String)null);
    var0.writeUserContent(var3);
    var0.writeContent("\n");
  }

  public static void renderMap(HtmlTemplateOutput jteOutput, HtmlInterceptor jteHtmlInterceptor, Map<String, Object> params) {
    String var3 = (String)var2.get("document1");
    String var4 = (String)var2.get("document2");
    render(var0, var1, var3, var4);
  }
}

If I use viewResolver with ContentType.Plain generated class uses TemplateOutput instead of HtmlTemplateOutput Which works well in local but fails in stage environment as we need to run this.templateEngine = TemplateEngine.createPrecompiled(ContentType.Plain);

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package gg.jte.generated.ondemand;

import gg.jte.TemplateOutput;
import gg.jte.html.HtmlInterceptor;
import java.util.Map;

public final class JtedocumentsGenerated {
  public static final String JTE_NAME = "documents.jte";
  public static final int[] JTE_LINE_INFO = new int[]{0, 0, 0, 0, 3, 3, 3, 6, 6, 7};

  public JtedocumentsGenerated() {
  }

  public static void render(TemplateOutput jteOutput, HtmlInterceptor jteHtmlInterceptor, String document1, String document2) {
    var0.writeContent("DOCUMENT 1:\n");
    var0.writeUserContent(var2);
    var0.writeContent("\n\nDOCUMENT 2:\n");
    var0.writeUserContent(var3);
    var0.writeContent("\n");
  }

  public static void renderMap(TemplateOutput jteOutput, HtmlInterceptor jteHtmlInterceptor, Map<String, Object> params) {
    String var3 = (String)var2.get("document1");
    String var4 = (String)var2.get("document2");
    render(var0, var1, var3, var4);
  }
}

Solution could be to change the default ContentType value from Html to Plain. One of the option which had tried is the following in build.gradle file with this approach generated classes not getting included in JAR file.

import gg.jte.ContentType
import java.nio.file.Paths
jte {
    generate()
}

tasks.precompileJte {
    sourceDirectory = Paths.get(project.projectDir.absolutePath, "src", "main", "jte")
    compilePath = sourceSets.main.runtimeClasspath
    contentType = ContentType.Plain
}

tasks.precompileJte {
    dependsOn(tasks.compileJava)
}

tasks.test {
    dependsOn(tasks.precompileJte)
}

Appreciate your suggestions to resolve this issue.

casid commented 11 months ago

I think you need to pass the correct content type to the generate gradle task, aka Plain.

venkatwilliams commented 11 months ago

What's the correct way to pass ContentType.Plain in generate Gradle task? Can you share some example.?

casid commented 11 months ago

I think it works like this:

jte {
    generate()
    contentType = ContentType.Plain
}
venkatwilliams commented 11 months ago

Thanks this Option worked perfectly.