Thursday, April 2, 2015

Re: Deferred binding consultation

I'm not 100% sure as I don't remember the details (not having worked on generators for a while) but I believe you should always return a non-null value (in your case).
IIRC, things go like this:
  • you can only generate a given class (by name) per compile. That means if you need to generate different classes depending on the permutation, you have to give them different names, and you can detect whether a given class has already been generated (by another permutation in the same compile) by doing a null-check on tryCreate's return value.
  • the value returned by the generator is the class to use, whichever the permutation it's been generated in (it doesn't even have to be generated, you can also just use an existing implementation, but have the generator dynamically select it rather than relying on –static– rebind rules in the module's gwt.xml).
So I'd say that in your case, you compile several permutations, and given the above rules, only the first one will use the generated class, others will just use GeneratedInterface given that the generator returns 'null'.

On Thursday, April 2, 2015 at 2:17:33 PM UTC+2, Vic wrote:
Hi All,

I am trying to use deferred binding to generate implementation in run-time and encountered with one problem. I created pretty simple generator and use GWT.create to instantiate a class. I am expecting GWT will provide class generated by my generator and it works as expected in dev mode. When I am trying to make same in production, for some reason GWT does not provide generated version. I have no idea what is wrong, maybe somebody have any ideas? Thanks in advance!  
Class, modified by generator
public class GeneratedInterface {

public String getValue(){
return null;
}
}

Generator
public String generate(TreeLogger logger, GeneratorContext ctx, String requestedClass) throws UnableToCompleteException {
JClassType type = ctx.getTypeOracle().findType(requestedClass);
String packageName = type.getPackage().getName();
String simpleName = type.getSimpleSourceName() + "_Generated";
logger.log(TreeLogger.Type.INFO, "Create adapter " + packageName + "." + simpleName + " for " + type.getQualifiedSourceName());
ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(packageName, simpleName);
composer.setSuperclass(GeneratedInterface.class.getName());
PrintWriter printWriter = ctx.tryCreate(logger, packageName, simpleName);
String className = null;
if (printWriter != null) {
SourceWriter writer = composer.createSourceWriter(ctx, printWriter);
writer.println("public String getValue() {");
writer.println(" return \"Test interface\";");
writer.println("}");
writer.commit(logger);
className = composer.getCreatedClassName();
}
return className;
}

EntryPoint 
public class GeneratorTest implements EntryPoint {

public void onModuleLoad() {
GeneratedInterface intf = GWT.create(GeneratedInterface.class);
log.info("deferred binding: " + intf.getClass().getName());
log.info("Value = " + intf.getValue());
    }
}

module.xml
<generate-with class="com.xxx.xxx.gwt.generator.server.TestGenerator">
<when-type-assignable class="com.xxx.xxx.gwt.generator.client.GeneratedInterface"/>
</generate-with>

As you can see, generator just provides implementation for GeneratedInterface.getValue() 

In case of dev mode, in logs I GWT uses generated class 
Thu Apr 02 15:14:23 MSK 2015 com.hp.usage.gwt.generator.client.GeneratorTest INFO: deferred binding: com.hp.usage.gwt.generator.client.GeneratedInterface_Generated
Thu Apr 02 15:14:23 MSK 2015 com.hp.usage.gwt.generator.client.GeneratorTest INFO: Value = Test interface

In case of production mode, in logs I GWT does not use generated class 
Thu Apr 02 15:15:53 GMT+300 2015 com.hp.usage.gwt.generator.client.GeneratorTest INFO: deferred binding: com.hp.usage.gwt.generator.client.GeneratedInterface
Thu Apr 02 15:15:53 GMT+300 2015 com.hp.usage.gwt.generator.client.GeneratorTest INFO: Value = null







--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment