Sunday, October 13, 2013

GWT Generator, Part 2: A very simple GWT generator example

I have divided the topic of GWT generator in three posts. This is the second installment which provides a simple GWT generator example. First one is here regarding what is GWT generator. And a third one here provides simple ways how you can debug your GWT generator.

Goal

Using GWT generator to find out the timestamp of when the GWT project was compiled. You can use this as a very simplified build ID.


Steps

Step1: Define an interface. The implementation of this interface will be generated at the compile time by the GWT generator. In my case, the interface is as follows:



Step2: Write a generator that will generate a class which implements this interface. In my case, the generator is as follows:



Step3: In the module xml, tell GWT compiler to generate any instance of BuildInfo interface with the above generator. In my case that section



Step4: Instantiate the BuildInfo interface through GWT.create(). Since I already have told the GWT compiler to generate any such case with the generator, the returned class will be actually generated with the above generator. After that simply use the returned class.



Step5: Compile and run the app in production mode. Or just run the app in development mode. You will be greeted with a popup alert, which will state something like below:


The timestamp in the above screenshot was actually generated by the BuildInfoGenerator, which kind of hard coded it when the web app was compiled.

That's it, that was a fully working example of GWT generator generating a class. Even though this specific generator does not add much functionality, this should give you the basic steps required of GWT generators.

If you want to download the complete Eclipse project for the above code, you can download it from the dropbox:

Download complete Eclipse GWT project as ZIP file


Few important points

  1. Instead of passing GWT.create() an interface, you can pass a concrete implementation too. If you return null from the generate() method, it will use the original class that was used as the argument of GWT.create(). This could be a good way only to generate the code when some special conditions are true, and not always. If the argument was an interface (as in my case), that will raise a compile time error.
  2. It's very important to understand, the generate method of the generator class (in my case BuildInfoGenerator) will be invoked more than once, one for each compile permutation.
  3. GeneratorContext.tryCreate() method (line 40) will return a PrintWriter if one already does not exist. Since generate method is called more than once, it means after the first time, tryCreate() will return null. It's very important that instead of returning null in such cases, you return the fully qualified class name (see line 42). Otherwise code generations will not work for these compile permutations, and you will be facing some very unintuitive behavior.

The Java code emitting as above is not very intuitive. I discussed some basic ways to debug this process here. If you are facing any problems, like compile errors or something else, do have a look.

No comments:

Post a Comment