Menu

Newbie first steps [help, please]

Help
ZioNemo
2007-04-19
2013-05-30
  • ZioNemo

    ZioNemo - 2007-04-19

    H All,
    I am trying to use FreeMaker, but I seem unable to use the default wrapper.
    I tried to compile (slightly modified) one of the trivial examples, but it fails miserably.
    Could someone point me in the right direction??
    Many thanks in Advance.

    If meaningful: what I need to do is to write a java application (no web) that should generate c-code from a certain model, so I need to access model fields, iterators, ...

    Current (failing) test code is:

    package com.softin.IOCbuilder.model;

    import java.io.File;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.Writer;

    import freemarker.template.Configuration;
    import freemarker.template.DefaultObjectWrapper;
    import freemarker.template.SimpleHash;
    import freemarker.template.Template;
    import freemarker.template.TemplateException;

    class TestObject {
        private String name;
        private int price;

        public TestObject(String name, int price) {
            this.name = name;
            this.price = price;
        }

        public String getName() {return name;}
        public int getPrice() {return price;}
       
        public double sin(double x) {
            return Math.sin(x);
        }

    public class Root {
        SimpleHash root = null;

        public Root() {
            root = new SimpleHash();
            root.put("theString", "wombat");
            root.put("theObject", new TestObject("green mouse", 1200));         
        }
       
        public static void main(String[] args) {
            Configuration cfg = new Configuration();
            try {
                cfg.setDirectoryForTemplateLoading(new File("templates"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            cfg.setObjectWrapper(new DefaultObjectWrapper());

            Template temp;
            try {
                temp = cfg.getTemplate("test.ftl");
                Root r = new Root();

                Writer out = new OutputStreamWriter(System.out);
                try {
                    temp.process(r.getRoot(), out);
                } catch (TemplateException e) {
                    e.printStackTrace();
                }
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }       
        }

        public SimpleHash getRoot() {
            return root;
        }

    }

    test template is:

    ${theString}
    ${theObject.name}
    ${theObject.price}
    ${theObject.sin(123)} 
    ======================================
    It fails on the second line.

    Again:
    Many thanks in advance
    Mauro

     
    • Nobody/Anonymous

      Hi Zionemo,

      Looks like you've made a good start. Only problem you seem to have here is the use of an internal class.

      I think Freemarker cannot properly inspect internal classes like the one you have created. If you break this out into a separate class it will run smoothly.

      -Pete

       
      • Attila Szegedi

        Attila Szegedi - 2007-04-19

        FM should be able to inspect inner classes just fine. However, a method is available to FreeMarker only if the method is public and is declared in a public class or interface. (Note this doesn't mean the class of the object must be public, but in that case the method must be declared in a public superclass or public implemented interface)

         
        • Nobody/Anonymous

          That'd be why then.

          As soon as I put the object in a separate class I instinctively made it public...

          -Pete

           
        • ZioNemo

          ZioNemo - 2007-04-19

          Hi Attila,
          I really tried to adhere to the manual, but it doesn't work for me :(

          Pretty please, could You look at my code (almost completely cut & paste from the manual) and point me in the right direction?.

          The getter methods are there ("public String getName()" is the first that fails).

          If I do not use the class inspection (e.g.: if I just use things put into SimpleHash) it works!

          It seems to me I'm missing something that will enable class inspection... but I don't know what!!

          If it's of any interest:
          I'm using sun jdk1.5.0_08 and its rte.
          I'm using eclipse 3.2.0.
          Using Project->Properties->FreeMarker Context->New I can define a theObject<->TestObject association and after that I *am* able to use code completion in the test.ftl file (e.g.: it will suggest name & price, but not sin() after I type "${theObject."
          Running the resulting class, however, will fail with:

          Apr 19, 2007 5:37:47 PM freemarker.log.JDK14LoggerFactory$JDK14Logger error
          SEVERE:

          Expression theObject.name is undefined on line 3, column 3 in test.ftl.
          The problematic instruction:
          ----------
          ==> ${theObject.name} [on line 3, column 1 in test.ftl]
          ...

          Please help.

          !!!!!!!!WAIT!!!!!!!!!!

          I just added a "public" to "class TestObject" and it worked!!!
          previously it was default.

          I will do some more tests.

          Thanks, for the time being!
          Mauro

           
    • ZioNemo

      ZioNemo - 2007-04-19

      Hi Pete,
      Thanks, but no joy :-((((

      i moved the TestObject class to its own file.

      If I modify the template to:
      ${theString}
      ${theObject}

      the program runs to completion with the following output:
      wombat
      com.softin.IOCbuilder.model.TestObject@b0f13d

      If I have a full template:
      ${theString}
      ${theObject}
      ${theObject.name}
      ${theObject.price}
      ${theObject.sin(123)} 

      it dies with:
      wombat
      com.softin.IOCbuilder.model.TestObject@ae000d

      Expression theObject.name is undefined on line 3, column 3 in test.ftl.
      The problematic instruction:
      ----------
      ==> ${theObject.name} [on line 3, column 1 in test.ftl]
      ----------

      Java backtrace for programmers:
      ----------
      freemarker.core.InvalidReferenceException: Expression theObject.name is undefined on line 3, column 3 in test.ftl.
          at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124)
          at freemarker.core.Expression.getStringValue(Expression.java:118)
          at freemarker.core.Expression.getStringValue(Expression.java:93)
          at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
          at freemarker.core.Environment.visit(Environment.java:196)
          at freemarker.core.MixedContent.accept(MixedContent.java:92)
          at freemarker.core.Environment.visit(Environment.java:196)
          at freemarker.core.Environment.process(Environment.java:176)
          at freemarker.template.Template.process(Template.java:232)
          at com.softin.IOCbuilder.model.Root.main(Root.java:39)
      Apr 19, 2007 3:46:57 PM freemarker.log.JDK14LoggerFactory$JDK14Logger error
      SEVERE:

      Expression theObject.name is undefined on line 3, column 3 in test.ftl.
      The problematic instruction:
      ----------
      ==> ${theObject.name} [on line 3, column 1 in test.ftl]
      ----------

      Java backtrace for programmers:
      ----------
      freemarker.core.InvalidReferenceException: Expression theObject.name is undefined on line 3, column 3 in test.ftl.
          at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124)
          at freemarker.core.Expression.getStringValue(Expression.java:118)
          at freemarker.core.Expression.getStringValue(Expression.java:93)
          at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
          at freemarker.core.Environment.visit(Environment.java:196)
          at freemarker.core.MixedContent.accept(MixedContent.java:92)
          at freemarker.core.Environment.visit(Environment.java:196)
          at freemarker.core.Environment.process(Environment.java:176)
          at freemarker.template.Template.process(Template.java:232)
          at com.softin.IOCbuilder.model.Root.main(Root.java:39)

      Expression theObject.name is undefined on line 3, column 3 in test.ftl.
      The problematic instruction:
      ----------
      ==> ${theObject.name} [on line 3, column 1 in test.ftl]
      ----------

      Java backtrace for programmers:
      ----------
      freemarker.core.InvalidReferenceException: Expression theObject.name is undefined on line 3, column 3 in test.ftl.
          at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124)
          at freemarker.core.Expression.getStringValue(Expression.java:118)
          at freemarker.core.Expression.getStringValue(Expression.java:93)
          at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
          at freemarker.core.Environment.visit(Environment.java:196)
          at freemarker.core.MixedContent.accept(MixedContent.java:92)
          at freemarker.core.Environment.visit(Environment.java:196)
          at freemarker.core.Environment.process(Environment.java:176)
          at freemarker.template.Template.process(Template.java:232)
          at com.softin.IOCbuilder.model.Root.main(Root.java:39)

      It really seems I cannot access anything inside the TestObject.
      What am I doing wrong?

      Thanks in Advance!
      Mauro

       

Log in to post a comment.