GXT 3 XTemplate: Custom Formatter – ClassNotFoundException

I am trying to use a custom formatter to turn a boolean into “Yes” or “No” and have run into a roadblock.

My IDE (Eclipse) does not indicate any errors but when I try to compile I receive

[ERROR] Annotation error: cannot resolve foobar.client.formatter.YesNoFormatter – exception: ClassNotFoundException

followed by a few other exceptions that appear to stem from this exception. I understand what a ClassNotFoundException indicates however I cannot figure out why I would be getting it since, as my code shows, the YesNoFormatter class is located in foobar.client.formatter and I can access it through

GWT.log("True: " + YesNoFactory.getFormat().format(Boolean.TRUE);

I am using GXT 3.1.0 and GWT 2.6.1.

Could anybody have an idea of why I am getting this exception? The example given at http://docs.sencha.com/gxt-guides/3/utility/xtemplates/XTemplates.html doesn’t mention anything (as far as I can see) about these classes needing to be in specific locations so I am at a loss.

EntryPoint:

package foobar.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.sencha.gxt.core.client.XTemplates.FormatterFactories;
import com.sencha.gxt.core.client.XTemplates.FormatterFactory;


public class TestClass implements EntryPoint {

    @FormatterFactories(@FormatterFactory(factory=YesNoFactory.class, name="yesNo"))
    public interface Renderer extends XTemplates {
      @XTemplate(source="yesNo.html")
       SafeHtml render(Boolean b);
    }

    @Override
    public void onModuledLoad() {
      GWT.log("True: " + YesNoFactory.getFormat().format(Boolean.TRUE);
      Renderer r = GWT.create(Renderer.class);

      Window.alert(r.render(true).asString());
    }
}

YesNo:

package foobar.client.formatter;

import com.sencha.gxt.core.client.XTemplates.Formatter;

public class YesNo implements Formatter<Boolean> {
   @Override
   public String format(Boolean data) {
      if (data == null) {
         return null;
      }
      return (data) ? "Yes" : "No";
   }
}

YesNoFactory:

package foobar.client.formatter;

public class YesNoFactory {
   public static YesNo getFormat() {
      return new YesNo();
   }
}

in foobar

<?xml version="1.0 encoding="UTF-8"?>
<module>
   <inherits name='com.google.gwt.user.User'/>
   <inherits name='com.sencha.gxt.GXT'/>

   <entry-point class='foobar.client.TestClass'/>

   <source path='client'/>
</module>

foobar/client/yesNo.html:

{b:yesNo()}

Answer

My formatter classes (YesNo and YesNoFactory) apparently have to be in a location that gets compiled prior to compiling the client-side code. After I moved these classes to my ‘shared’ package – the package that houses code used by the client and server – everything worked.

This was not obvious in the XTemplates portion of the guide at http://docs.sencha.com/gxt-guides/3/utility/xtemplates/XTemplates.html which does not seem to specify where the files used for custom formatters need to be located. Maybe that should have been obvious but not to me.

Leave a Reply

Your email address will not be published. Required fields are marked *