Implementation of mustache.js for Java

Overview

Mustache.java Build Status FOSSA Status

Mustache.java is not designed to allow untrusted parties to provide templates. It may be possible to lock it down to provide that safely, but by default it is UNSAFE. Use the SafeMustacheFactory and whitelist all templates and partials.

As of release 0.9.0 mustache.java is now Java 8 only. For Java 6/7 support use 0.8.x.

There are no external dependencies and the compiler library is ~100k.

Mustache.java is a derivative of mustache.js.

There is a Google Group for support and questions: http://groups.google.com/group/mustachejava

Travis CI: https://travis-ci.org/spullara/mustache.java

API documentation: http://spullara.github.io/mustache/apidocs/

Largest production deployment of Mustache.java:

  • Twitter (the web site, email, syndicated widgets, etc)

Thanks to YourKit for many performance improvements:

YourKit is kindly supporting the mustache.java open source project with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products:

Request for contributions:

  • Real world benchmarks that matter - currently benchmarking based on Twitter templates
  • Documentation
  • Bug reports / fixes
  • API feedback
  • Optimizations

Documentation:

  • Javadocs
  • Mustache.js manual
  • Passes all of the mustache specification tests modulo whitespace differences
  • Biggest difference between mustache.js and mustache.java is optional concurrent evaluation
  • Data is provided by objects in an array of scopes and are accessed via non-private fields, methods or maps
  • Any Iterable can be used for list-like behaviors
  • Returning a Callable allows for concurrent evaluation if an ExecutorService is configured
  • Template inheritance is supported by this implementation, see https://github.com/mustache/spec/issues/38 (eg. {{<super}}{{$content}}...{{/content}}{{/super}})
  • Additional functions/lambdas (eg. {{#func1}}...{{/func1}}) are implemented using Function from Java 8 (post-substitution)
  • Use TemplateFunction if you want mustache.java to reparse the results of your function/lambda (pre-substitution)
  • Both default and manually configured classpath based and file system based template roots are supported
  • A compiled and invokedynamic version is available. Performance improvements are often application specific.
  • The handlebar server will render templates + json data for quick mockups of templates by designers
  • Completely pluggable system for overriding almost all the behavior in the compilation and rendering process
  • You can pull out sample data from live systems using the CapturingMustacheVisitor for mocks and tests
  • The DecoratedCollection can provide first / last / index for elements in a collection
  • The invert call can take text and a template and solve for the data

Performance:

  • See the com.github.mustachejavabenchmarks package in the compiler module
  • Compiles 4000+ timeline.html templates per second per core
  • Renders 3000+ of 50 tweet timelines per second per core on 2011 Macbook Pro / MacPro hardware
  • New codegen module generates code for guards and mustaches
  • The indy module uses the codegen module and invokedynamic to compile templates down to bytecode

Build suggestions:

  • Don't build, use Maven dependencies
  • If you must build but not test:
  • If you must build and test but not benchmark:
    • CI=1 mvn clean install -pl :compiler -am
  • If you must build, test and benchmark:
    • mvn clean install

Maven dependency information (ie. for most common cases you will just need the compiler module):

Java 8+:

<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.9.10</version>
</dependency>

Java 6/7:

<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.8.18</version>
</dependency>

Example template file:

{{#items}}
Name: {{name}}
Price: {{price}}
  {{#features}}
  Feature: {{description}}
  {{/features}}
{{/items}}

Might be powered by some backing code:

public class Context {
  List<Item> items() {
    return Arrays.asList(
      new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))),
      new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly.")))
    );
  }

  static class Item {
    Item(String name, String price, List<Feature> features) {
      this.name = name;
      this.price = price;
      this.features = features;
    }
    String name, price;
    List<Feature> features;
  }

  static class Feature {
    Feature(String description) {
       this.description = description;
    }
    String description;
  }
}

And would result in:

Name: Item 1
Price: $19.99
  Feature: New!
  Feature: Awesome!
Name: Item 2
Price: $29.99
  Feature: Old.
  Feature: Ugly.

Evaluation of the template proceeds serially. For instance, if you have blocking code within one of your callbacks, the system will pause while executing them:

static class Feature {
  Feature(String description) {
    this.description = description;
  }

  String description() throws InterruptedException {
    Thread.sleep(1000);
    return description;
  }
}

If you change description to return a Callable instead it will automatically be executed in a separate thread if you have provided an ExecutorService when you created your MustacheFactory.

Callable<String> description() throws InterruptedException {
  return new Callable<String>() {

    @Override
    public String call() throws Exception {
      Thread.sleep(1000);
      return description;
    }
  };
}

This enables scheduled tasks, streaming behavior and asynchronous i/o. Check out the example module in order to see a complete end-to-end example:

package mustachejava;

import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheFactory;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;

public class Example {

  List<Item> items() {
    return Arrays.asList(
      new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))),
      new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly.")))
    );
  }

  static class Item {
    Item(String name, String price, List<Feature> features) {
      this.name = name;
      this.price = price;
      this.features = features;
    }

    String name, price;
    List<Feature> features;
  }

  static class Feature {
    Feature(String description) {
      this.description = description;
    }

    String description;
  }

  public static void main(String[] args) throws IOException {
    MustacheFactory mf = new DefaultMustacheFactory();
    Mustache mustache = mf.compile("template.mustache");
    mustache.execute(new PrintWriter(System.out), new Example()).flush();
  }
}

An alternative approach for providing variables would be to use a Map object, like:

  public static void main(String[] args) throws IOException {
    HashMap<String, Object> scopes = new HashMap<String, Object>();
    scopes.put("name", "Mustache");
    scopes.put("feature", new Feature("Perfect!"));

    Writer writer = new OutputStreamWriter(System.out);
    MustacheFactory mf = new DefaultMustacheFactory();
    Mustache mustache = mf.compile(new StringReader("{{name}}, {{feature.description}}!"), "example");
    mustache.execute(writer, scopes);
    writer.flush();
  }

License

FOSSA Status

Comments
  • Disable encoding for certain variables

    Disable encoding for certain variables

    #147 demonstrates how Mustache can be customized to enable/disable encoding/escaping of values (e.g., to HTML entities), and it works for me.

    However, there are cases where I'd like to enable escaping (global/by default), then for selected variables, I'd like to disable encoding regardless if the template uses {{ or {{{.

    For example,

    Hello {{nonEncodable}}, this is {{encodable}}
    

    where nonEncodable is <b>1</b> and encodable is <b>2</b>, should render as:

    Hello <b>1</b>, this is &lt;b&gt;2&lt;/b&gt;
    

    I can almost do it by overriding com.github.mustachejava.DefaultMustacheFactory#encode:

      @Override
      public void encode(String value, Writer writer) {
        escape(value, writer);
      }
    

    but if only we have the parameter Object object which is the source of that value (the one in oh.stringify(object)), so I can check whether that object possess the marker of whether escaping should be done or not.

    Let me know if there is a better way to achieve the same.

    opened by kenston 14
  • Sometimes (?) we get java.lang.AssertionError: Unexpected guard failure: [com.github.mustachejava.reflect.MissingWrapper@1de0a172] at com.github.mustachejava.reflect.GuardedBinding.createAndGet(GuardedBinding.java:88)

    Sometimes (?) we get java.lang.AssertionError: Unexpected guard failure: [com.github.mustachejava.reflect.MissingWrapper@1de0a172] at com.github.mustachejava.reflect.GuardedBinding.createAndGet(GuardedBinding.java:88)

    using com.github.spullara.mustache.java v0.8.12

    HTTP Status 500 - javax.servlet.ServletException: Throwable

    type Exception report

    message javax.servlet.ServletException: Throwable

    description The server encountered an internal error that prevented it from fulfilling this request.

    exception

    org.soluvas.web.site.SiteException: javax.servlet.ServletException: Throwable
        id.co.bippo.springapp.SoluvasAtmosphereHandler.onRequest(SoluvasAtmosphereHandler.java:78)
        org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:259)
        org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166)
        org.atmosphere.container.Tomcat7CometSupport.service(Tomcat7CometSupport.java:88)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.doService(Tomcat7AsyncSupportWithWebSocket.java:63)
        org.atmosphere.container.TomcatWebSocketUtil.doService(TomcatWebSocketUtil.java:87)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.service(Tomcat7AsyncSupportWithWebSocket.java:59)
        org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1441)
        org.atmosphere.cpr.AtmosphereServlet.event(AtmosphereServlet.java:361)
        org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1653)
        java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        java.lang.Thread.run(Thread.java:722)
    

    root cause

    javax.servlet.ServletException: Throwable
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.doFilter(SoluvasAtmosphereHandler.java:174)
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.invokeFilterChain(SoluvasAtmosphereHandler.java:158)
        id.co.bippo.springapp.SoluvasAtmosphereHandler.onRequest(SoluvasAtmosphereHandler.java:76)
        org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:259)
        org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166)
        org.atmosphere.container.Tomcat7CometSupport.service(Tomcat7CometSupport.java:88)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.doService(Tomcat7AsyncSupportWithWebSocket.java:63)
        org.atmosphere.container.TomcatWebSocketUtil.doService(TomcatWebSocketUtil.java:87)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.service(Tomcat7AsyncSupportWithWebSocket.java:59)
        org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1441)
        org.atmosphere.cpr.AtmosphereServlet.event(AtmosphereServlet.java:361)
        org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1653)
        java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        java.lang.Thread.run(Thread.java:722)
    

    root cause

    javax.servlet.ServletException: Throwable
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.doFilter(SoluvasAtmosphereHandler.java:174)
        org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
        org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
        org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
        org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
        org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
        org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
        org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.doFilter(SoluvasAtmosphereHandler.java:172)
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.invokeFilterChain(SoluvasAtmosphereHandler.java:158)
        id.co.bippo.springapp.SoluvasAtmosphereHandler.onRequest(SoluvasAtmosphereHandler.java:76)
        org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:259)
        org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166)
        org.atmosphere.container.Tomcat7CometSupport.service(Tomcat7CometSupport.java:88)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.doService(Tomcat7AsyncSupportWithWebSocket.java:63)
        org.atmosphere.container.TomcatWebSocketUtil.doService(TomcatWebSocketUtil.java:87)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.service(Tomcat7AsyncSupportWithWebSocket.java:59)
        org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1441)
        org.atmosphere.cpr.AtmosphereServlet.event(AtmosphereServlet.java:361)
        org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1653)
        java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        java.lang.Thread.run(Thread.java:722)
    root cause
    
    java.lang.AssertionError: Unexpected guard failure: [com.github.mustachejava.reflect.MissingWrapper@1de0a172] [{category=null, appManifest=org.apache.wicket.proxy.LazyInitProxyFactory$JdkHandler@1e5a62d5, webAddress=org.apache.wicket.proxy.LazyInitProxyFactory$JdkHandler@400e9d84}]
        com.github.mustachejava.reflect.GuardedBinding.createAndGet(GuardedBinding.java:88)
        com.github.mustachejava.reflect.GuardedBinding.get(GuardedBinding.java:74)
        com.github.mustachejava.codes.DefaultCode.get(DefaultCode.java:103)
        com.github.mustachejava.codes.ValueCode.execute(ValueCode.java:52)
        com.github.mustachejava.codes.DefaultMustache.run(DefaultMustache.java:30)
        com.github.mustachejava.codes.DefaultCode.execute(DefaultCode.java:119)
        com.github.mustachejava.codes.DefaultCode.execute(DefaultCode.java:108)
        org.soluvas.web.site.pagemeta.impl.PageMetaImpl.renderMustache(PageMetaImpl.java:738)
        org.soluvas.web.site.pagemeta.impl.PageMetaImpl.toText(PageMetaImpl.java:710)
        org.soluvas.web.site.RulesPageMetaProvider.get(RulesPageMetaProvider.java:95)
        sun.reflect.GeneratedMethodAccessor236.invoke(Unknown Source)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        java.lang.reflect.Method.invoke(Method.java:601)
        org.apache.wicket.proxy.LazyInitProxyFactory$JdkHandler.invoke(LazyInitProxyFactory.java:435)
        com.sun.proxy.$Proxy102.get(Unknown Source)
        org.soluvas.web.bootstrap.BootstrapPage$1.load(BootstrapPage.java:239)
        org.soluvas.web.bootstrap.BootstrapPage$1.load(BootstrapPage.java:228)
        org.apache.wicket.model.LoadableDetachableModel.getObject(LoadableDetachableModel.java:121)
        org.apache.wicket.model.AbstractPropertyModel.getInnermostModelOrObject(AbstractPropertyModel.java:269)
        org.apache.wicket.model.AbstractPropertyModel.getObject(AbstractPropertyModel.java:83)
        org.apache.wicket.AttributeModifier.getReplacementOrNull(AttributeModifier.java:226)
        org.apache.wicket.AttributeModifier.replaceAttributeValue(AttributeModifier.java:182)
        org.apache.wicket.AttributeModifier.onComponentTag(AttributeModifier.java:164)
        org.apache.wicket.Component.renderComponentTag(Component.java:3969)
        org.apache.wicket.Component.internalRenderComponent(Component.java:2539)
        org.apache.wicket.MarkupContainer.onRender(MarkupContainer.java:1493)
        org.apache.wicket.Component.internalRender(Component.java:2378)
        org.apache.wicket.Component.render(Component.java:2306)
        org.apache.wicket.MarkupContainer.renderNext(MarkupContainer.java:1390)
        org.apache.wicket.MarkupContainer.renderAll(MarkupContainer.java:1554)
        org.apache.wicket.Page.onRender(Page.java:876)
        org.apache.wicket.markup.html.WebPage.onRender(WebPage.java:142)
        org.apache.wicket.Component.internalRender(Component.java:2378)
        org.apache.wicket.Component.render(Component.java:2306)
        org.apache.wicket.Page.renderPage(Page.java:1010)
        org.apache.wicket.request.handler.render.WebPageRenderer.renderPage(WebPageRenderer.java:116)
        org.apache.wicket.request.handler.render.WebPageRenderer.respond(WebPageRenderer.java:196)
        org.apache.wicket.core.request.handler.RenderPageRequestHandler.respond(RenderPageRequestHandler.java:165)
        org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:861)
        org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64)
        org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:261)
        org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:218)
        org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:289)
        org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:259)
        org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:201)
        org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:282)
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.doFilter(SoluvasAtmosphereHandler.java:172)
        org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
        org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
        org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
        org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
        org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
        org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
        org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.doFilter(SoluvasAtmosphereHandler.java:172)
        id.co.bippo.springapp.SoluvasAtmosphereHandler$CustomFilterChain.invokeFilterChain(SoluvasAtmosphereHandler.java:158)
        id.co.bippo.springapp.SoluvasAtmosphereHandler.onRequest(SoluvasAtmosphereHandler.java:76)
        org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:259)
        org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166)
        org.atmosphere.container.Tomcat7CometSupport.service(Tomcat7CometSupport.java:88)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.doService(Tomcat7AsyncSupportWithWebSocket.java:63)
        org.atmosphere.container.TomcatWebSocketUtil.doService(TomcatWebSocketUtil.java:87)
        org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket.service(Tomcat7AsyncSupportWithWebSocket.java:59)
        org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1441)
        org.atmosphere.cpr.AtmosphereServlet.event(AtmosphereServlet.java:361)
        org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1653)
        java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        java.lang.Thread.run(Thread.java:722)
    

    note The full stack trace of the root cause is available in the Apache Tomcat/7.0.30 logs.

    Apache Tomcat/7.0.30

    Original issue: https://github.com/soluvas/soluvas-web/issues/29

    opened by ceefour 12
  • Add key to PGP keys map

    Add key to PGP keys map

    opened by silnith 10
  • java.lang.IllegalArgumentException: object is not an instance of declaring class

    java.lang.IllegalArgumentException: object is not an instance of declaring class

    Sometimes we get this exception in Mustache. Strangely it happens on only a few nodes, after a restart it happens on some other nodes.

    Is it familiar to anyone?

    java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_51]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_51]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_51]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_51]
    at com.github.mustachejava.reflect.ReflectionWrapper.call(ReflectionWrapper.java:63) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.reflect.ReflectionObjectHandler.unwrap(ReflectionObjectHandler.java:34) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.reflect.guards.WrappedGuard.apply(WrappedGuard.java:33) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.reflect.GuardedWrapper.guardCall(GuardedWrapper.java:40) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.reflect.ReflectionWrapper.call(ReflectionWrapper.java:57) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.reflect.GuardedBinding.get(GuardedBinding.java:66) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultCode.get(DefaultCode.java:105) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.ValueCode.execute(ValueCode.java:55) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultMustache.run(DefaultMustache.java:30) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultCode.execute(DefaultCode.java:126) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.writeTemplate(IterableCode.java:114) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.handleFunction(IterableCode.java:101) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.handle(IterableCode.java:37) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.execute(IterableCode.java:29) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultMustache.run(DefaultMustache.java:30) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultCode.run(DefaultCode.java:171) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.next(IterableCode.java:123) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.reflect.BaseObjectHandler.iterate(BaseObjectHandler.java:86) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.execute(IterableCode.java:118) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.handle(IterableCode.java:41) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.IterableCode.execute(IterableCode.java:29) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultMustache.run(DefaultMustache.java:30) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultCode.execute(DefaultCode.java:126) ~[compiler-0.8.13.jar:na]
    at com.github.mustachejava.codes.DefaultCode.execute(DefaultCode.java:115) ~[compiler-0.8.13.jar:na]
    

    After about 15 cases it changes to a ClassCastException in a GeneratedMethodAccessor due to inflation.

    opened by rustyx 10
  • Bug on function where variable is used?

    Bug on function where variable is used?

    I want to create a basic function toUpperCase().

    I made a sample but it does not work. I think it is a bug.

    This my code

    public static void main(String[] args)
    {
        Map<String, Object> scopes = new HashMap<String, Object>();
        scopes.put("map", new HashMap<String, String>(){{put("key", "value");}});
        final Function<String, String> upperFunction = new TemplateFunction()
        {
    
            @Override
            public String apply(String aInput)
            {
                return aInput.toUpperCase();
            }
        };
        scopes.put("upper", upperFunction);
    
    
        Writer writer = new OutputStreamWriter(System.out);
        MustacheFactory mf = new DefaultMustacheFactory();
        Mustache mustache = mf.compile(new StringReader("map.key={{map.key}}{{#upper}}, in #upper map.key={{map.key}}{{/upper}} \n" +
                "in #map{{#map}}, in #upper {{#upper}} keyInUpper={{key}} {{/upper}} {{/map}} "), "example");
    
        mustache.execute(writer, scopes);
        try
        {
            writer.flush();
        }
        catch (IOException e)
        {
            //
        }
    }
    

    This is the output

    map.key=value, IN #UPPER MAP.KEY= in #map, in #upper KEYINUPPER=

    should be

    map.key=value, IN #UPPER MAP.KEY=VALUE in #map, in #upper KEYINUPPER=VALUE

    Tell me if it is a bug or what is wrong in my code.

    opened by alexandrenavarro 10
  • no build instructions or jar file

    no build instructions or jar file

    I did a git clone, and I don't see any jar file or build instructions.

    I see a pom file. I'm not too familiar with maven (and am not intending to use it anywhere else, so please don't make us learn too much about it).

    I installed maven and tried typing 'mvn compile', which took ages downloading stuff, gave lots of warnings like "Authorization failed: Access denied to: http://repository.jboss.org/maven2/org/apache/maven/maven-project/2.0.8/maven-project-2.0.8.pom", eventually said "succeeded," but didn't produce a jar file. Is there some simple way to get a jar file containing everything I need to try out mustache in my own non-maven project?

    opened by nairbv 10
  • Illegal reflective access by mustachejava.reflect.BaseObjectHandler

    Illegal reflective access by mustachejava.reflect.BaseObjectHandler

    Hello, my software is throwing the following error when building:

    WARNING: Illegal reflective access by com.github.mustachejava.reflect.BaseObjectHandler to to method java.util.HashMap$Node.getKey()
    WARNING: Please consider reporting this to the maintainers of com.github.mustachejava.reflect.BaseObjectHandler
    

    Are there any mitigation strategies/ plans to fix this?

    opened by liamsdunn 9
  • Fixed whitespace handling for partials

    Fixed whitespace handling for partials

    As mentioned in #211 the handling of whitespace for partials of mustache.java is not conforming to the mustache spec.

    This PR fixes this (only for partials though).

    Basic idea is to memorize the indentation of a partial and to pass it through during execution via a custom writer.

    This is not yet finished, as this obviously broke some other tests (as the whitespace differs). I just wanted to know if this is at all a direction that would be considered for merging.

    opened by dpoetzsch 9
  • Scala Maps don't work

    Scala Maps don't work

    FYI, I'm trying to use play-2-mustache plugin which uses mustache.java and Scala maps reflection isn't working. An option is returned instead of the value object. This may be a twitter library issue in the end, but wanted to let people know. java.util.HashMap work of course so that's what we're using for now.

    opened by ghost 9
  • Optionally support access to non get(key) methods on instances of Map

    Optionally support access to non get(key) methods on instances of Map

    This allows for access to methods other than get(key) on classes that implement Map. The feature is off by default, but can by activated by setting an option on ObjectHandler.

    The only thing that I don't like about this is that if you access an instance of Map and fall back to a method, but later use the same template with a different Map containing a matching key, the method call will be used first due to the wrapper caching (I think). However, it's a corner case, and I don't see a solution for it other than moving wrapper caching into the ObjectHandler or some similar refactoring.

    opened by MattCheely 9
  • Can't be used with Scala 2.11

    Can't be used with Scala 2.11

    The version of scala-library is out of date by nearly 4 years. Scala 2.11 has removed a lot of things that ScalaObjectHandler uses, for example asJavaMap.

    I'd like to propose that we should remove the ScalaObjectHandler and TwitterObjectHandler from the compiler project. We could then release a separate jar, versioned for different Scala versions, that allows people using 2.8, 2.9, 2.10 or 2.11 by having ObjectHandlers specialised for those versions.

    This would allow anyone to use the compiler.jar and then required the specific scala based jar for the object handlers.

    opened by michaeldfallen 8
  • Better option of handling missing template variables?

    Better option of handling missing template variables?

    Hi,

    I'm looking for some nice way how to handle missing variables in Mustache templates during the execution.

    final MustacheFactory factory = ...;
    final Mustache template = factory.compile(new StringReader("Hello, {{name}}!", "test-template"));
    
    // 'name' variable not provided here,
    // renders the template without any issue, but I'd need it to fail at this point
    template.execute(writer, Map.of());
    

    The only feasible way I found, when I need to get both missing variable name and template name is this:

        private static MustacheFactory checkMissingVariablesMustacheFactory() {
            final DefaultMustacheFactory mustacheFactory = new DefaultMustacheFactory();
            mustacheFactory.setObjectHandler(new ReflectionObjectHandler() {
                @Override
                public Binding createBinding(String name, TemplateContext tc, Code code) {
                    return new GuardedBinding(this, name, tc, code) {
                        @Override
                        protected synchronized Wrapper getWrapper(String name, List<Object> scopes) {
                            final Wrapper wrapper = super.getWrapper(name, scopes);
    
                            if (wrapper instanceof MissingWrapper) {
                                throw new MissingTemplateVariableException(tc.file(), name);
                            }
    
                            return wrapper;
                        }
                    };
                }
            });
    
            return mustacheFactory;
        }
    

    It's working nice, but it's quite verbose. Is there any easier way to do that, or if not, did you consider adding some kind of handler for this case?

    Thank you and thanks for this great library!

    opened by vaclavsvejcar 0
  • Lambda context support (for JStachio fallback)

    Lambda context support (for JStachio fallback)

    So I recently early released a mustache type checked library called JStachio: https://github.com/jstachio/jstachio

    While it may seems like JStachio is a competing Mustache implementation I think its complementary to both this library and JMustache. It actually can help users of mustache.java for type checking structured models (jstachio is not good at Map<String,?> models) while delegating to mustache.java for dynamic models.

    JStachio delegating to either JMustache or mustache.java also allows more rapid development of templates as unfortunately incremental compilation via annotation processor for resources is problematic. Then in production one can turn off delegating and rely on the jstachio generated java code or not.

    Anyway I could not figure out how to get a 1:1 support of lambdas in JStachio to mustache.java like I was with JMustache because it appears there is no way to get context from a lambda.

    Is that correct? Am I missing something? I realize this isn't really part of the mustache spec but many implementations allow access.

    Regardless @spullara any feedback on the library would be greatly appreciated.

    opened by agentgt 0
  • Path nio File

    Path nio File

    https://github.com/spullara/mustache.java/pull/273 (Add FileSystemResolver(Path) constructor ) was merged into main on 6 Oct 2021, but isn't part of release 0.9.10

    Simple to build from main, or even copy/paste the enhanced FileSystemResolver, but would be nice to have as the nio Path usage allows for mocking the filesystem with jmfs

    opened by jbeaken 0
  • Update tests for jUnit 4.x

    Update tests for jUnit 4.x

    • Remove usage of jUnit 3.x TestCase
    • Introduce use of assertThrows() from jUnit 4.x
    • Clean up exception declarations in tests
    • Replace hamcrest assertions with jUnit assertions

    I considered going straight to v5 but this seemed like a big enough diff

    I also converted BenchmarkTest to a jUnit test class and removed its main method - is that OK?

    This also removes all usage of fail(), replaced by assertThrows()

    opened by rhowe 3
  • Deferred loading of partials

    Deferred loading of partials

    Given template:

    {{#enable}}{{>rsrc.html}}{{/enable}}
    

    with enable variable usually false (i.e., null), the rsrc.html is always loaded/read even if it will not be used. I think it makes sense, since during compilation it wouldn't know if it's going to be used or not, and since compilation is ideally a one-time thing.

    Since I compile the template on-demand rather than re-use the Mustache object, is it possible to do compilation of the template that defers the reading of rsrc.html only when actually needed? Or to combine compile and template's execute into one so that it would know that it didn't have to load rsrc.html?

    I assume com.github.mustachejava.DeferringMustacheFactory with docs:

    This allows you to automatically defer evaluation of partials. By default it generates HTML but you can override that behavior.

    isn't appropriate for my case, right?

    Example code:

    MustacheFactory mf = new DefaultMustacheFactory(new DefaultResolver() {
                public Reader getReader(String resourceName) {
                    System.out.println("  Called getReader: " + resourceName);
                    return new StringReader("contentBeingIncluded");
                }
            });
    
    mf.compile(new StringReader("{{#enable}}{{>rsrc}}{{/enable}}"), "example1");
    

    Actual Output:

      Called getReader: rsrc.html
    
    opened by kenston 0
  • NullPointerException when context ClassLoader retrieves the Bootstrap Class Loader

    NullPointerException when context ClassLoader retrieves the Bootstrap Class Loader

    Within the ClassPathResolver a ClassLoader is used to retrieve a URL resource in the getReader method. This class loader is retrieved from the current thread's defined context class loader. However, if the current thread's context class loader is only Java's bootstrap class loader, the value returned is null.

    This causes a null pointer exception to occur when the code attempts to use the bootstrap class loader. Would it be possible to have an exception thrown that the context class loader needs a parent class loader to properly retrieve resources?

    Maybe there could be a future solution to the issue to allow that class loader to be optionally defined as an argument that can be passed into that method.

    opened by Macinto5h 0
Daily mail subscription implementation using Java Spring-boot and Quartz Scheduler

Daily Mail Subscription Service POC Implemented using Java Spring-boot and Quartz Scheduler Working Application Exposing 3 endpoints /subscription/cre

null 16 Jun 3, 2022
Pure Java implementation of ONCRPC/SUNRPC

ONCRPC4J This is a part of dCache.ORG's NFSv4.1 work. Technically, this is not a fork of Remote Tea RPC library, but formally it is as we was inspired

dCache Project 26 Oct 27, 2022
Pure Java NFSv3 and NFSv4.1 implementation

NFS4J The pure java implementation of NFS server version 3, 4.0 and 4.1 including pNFS extension with nfs4.1-files and flex-files layout types. Buildi

dCache Project 189 Dec 13, 2022
Hashids algorithm v1.0.0 implementation in Java

Hashids.java A small Java class to generate YouTube-like hashes from one or many numbers. Ported from javascript hashids.js by Ivan Akimov What is it?

YoMo 944 Dec 29, 2022
This repository contains CQRS implementation in Java

CQRS Design Pattern Java This repository contains CQRS implementation in Java. I've written this code-base step by step on Medium that is my Turkish c

Yusuf Yılmaz 14 Oct 25, 2022
SimpleIcons4J is a Java implementation of the simple-icons JavaScript library

SimpleIcons4J SimpleIcons4J is a Java implementation of the simple-icons JavaScript library and is inspired by simpleicons.org. This library currently

Hyesung Lee 3 Apr 9, 2022
This program is a simple machine learning implementation in Java for detecting skin pixels.

Skin Detector ?? ?? Detects human skin from images This program is a simple machine learning implementation in Java for detecting skin pixels. How to

Tasmia Zerin 1 Jan 21, 2022
Java implementation of Beacon Chain for Ethereum 2.0, and its Backend API and full Infrastructure.

hailong Implementation of the Ethereum 2.0 Beacon Chain. Based on the (evolving) specification. Build Instructions Install Prerequisites 1) Java 11 Ub

我是高天才! 14 Feb 6, 2022
Search API with spelling correction using ngram-index algorithm: implementation using Java Spring-boot and MySQL ngram full text search index

Search API to handle Spelling-Corrections Based on N-gram index algorithm: using MySQL Ngram Full-Text Parser Sample Screen-Recording Screen.Recording

Hardik Singh Behl 5 Dec 4, 2021
This project illustrates TDD & Clean Architecture implementation in Java

Banking Kata - Java Overview This project illustrates TDD & Clean Architecture implementation in Java, showing the Use Case Driven Development Approac

Valentina Cupać 191 Dec 28, 2022
A implementation of shadowsocks that base on java's netty framework

Shadowsocks shadowsocks is a fast tunnel proxy that helps you bypass firewalls. shadowsocks-java is a implementation of shadowsocks protocol that base

bigbyto 36 Oct 17, 2022
Budget Proof Key for Code Exchange (PKCE) implementation using Java Spring-boot

Low Budget Proof Key for Code Exchange (PKCE) Implementation using Java Spring-boot Just for fun, low budget implementation of PKCE Auth Flow using a

Hardik Singh Behl 10 Dec 11, 2022
The Java implementation of "A Survey of Trajectory Distance Measures and Performance Evaluation". VLDBJ 2020

A Survey of Trajectory Distance Measures and Performance Evaluation The Java implementation of the following paper: Han Su, Shuncheng Liu, Bolong Zhen

Shuncheng Liu 99 Oct 19, 2022
JSON Web Token implementation for Java according to RFC 7519. Easily create, parse and validate JSON Web Tokens using a fluent API.

JWT-Java JSON Web Token library for Java according to RFC 7519. Table of Contents What are JSON Web Tokens? Header Payload Signature Features Supporte

Bastiaan Jansen 6 Jul 10, 2022
Java implementation of GPT2 tokenizer.

GPT2 Tokenizer Java Java implementation of GPT2 tokenizer Requirements Please install the following dependencies to use the library. implementation 'c

Kevin Ko 14 Jan 4, 2023
A simple implementation of the Dubbo protocol.

Codec-dubbo Codec-dubbo is a binary codec framework for dubbo protocol Features Fully compatible with Dubbo protocol Completely rewritten based on Net

ESA Stack 13 Nov 21, 2022
Realtime Data Processing and Search Engine Implementation.

Mutad The name Mutad is a reverse spelling of datum. Overview An implementation of a real-time data platform/search engine based on various technology

Shingo OKAWA 14 Aug 4, 2022
A Graphics2D implementation targeting Skija as a backend.

SkijaGraphics2D Version 1.0.2, 4 August 2021 Overview SkijaGraphics2D is an implementation of Java2D's Graphics2D API that targets Skia via the Skija

David Gilbert 46 Dec 29, 2022
A minimal WHIP implementation for the Raspberry Pi. It sends Mic and Camera to a WHIP endpoint

whipi A minimal WHIP implementation for the Raspberry Pi. It sends Camera Mic to a WHIP endpoint. Requires a Raspberry Pi with a PiCam and Java 11. It

|pipe| 12 Oct 27, 2022