What does GWT.create mean and why should I use it? - gwt

I am new to GWT. i have below line of code.
SomeClientServiceAsync someService = GWT.create(SomeClientService.class);
what does above line means and why cannot i use any other alternatives to instantiate it?
Please help me!
Thanks.

GWT.create is used for deferred binding. This allows you to supply different implementations of the same service based on the user's browser. See the following question:
Why use GWT.create() instead of new?
If you do not need to have multiple implementations of your service, just create it via new!

GWT works by creating a service just like RMI does. Here you are creating the service SomeClientService which resides in the client package. It contains all the functions that can be called server-side.

GWT.create works in different ways:
It tries to see if in the gwt.xml files there is no declaration of which implementation to use depending on a GWT property. This GWT property can be the well known user agent which in this case will have the effect of selecting different implementations for each browser, but it can also be used for other things, for example to disable logging (the fact that logging is enabled or not has nothing to do with in which browser it runs)
Example:
<replace-with class="com.x.app.client.ui.base.button.CustomSlicedButtonCellAppearance">
<when-type-is class="com.x.app.client.ui.base.button.CustomButtonCellAppearance" />
<when-property-is name="gxt.css3.enabled" value="false"/>
<when-property-is name="gxt.theme" value="themeName" />
</replace-with>
In this case it will use CustomSlicedButtonCellAppearance for a call to GWT.create(CustomButtonCellAppearance.class) only if css3 is not supported and for the given theme. Notice that "when-property-is" is optional, and if not supplied it will always use that implementation for the given interface.
It also looks for generators, in which case a new class is generated during GWT compilation (or in devmode) usually based on annotation that are present in the interface passed to the create method.
Example:
<generate-with class="org.fusesource.restygwt.rebind.RestServiceGenerator">
<when-type-assignable class="org.fusesource.restygwt.client.RestService" />
</generate-with>
In this case the RestServiceGenerator will generate code to submit the request.
Another example is how UIBinder works: besides using the annotations in the interface it also generates code based on what is inside the ui.xml file.
If no declaration matches the class/interface passed to the GWT.create method, then it will try to do a new on that class (in case of an interface it will fail).
Declarations in gwt.xml files can be overwritten by other declarations that are processed afterwards, so if you are using a module which declares a rule you can change that rule by declaring a new rule after the inherits declaration of the module containing the original declaration.

Related

How to get rid of this useless GWT compiler warning?

There is an option in GWT to obfuscate enum names:
<set-configuration-property name="compiler.enum.obfuscate.names" value="true" />
When I use this option, my compiles produce a warning:
[WARN] Call to Enum method name when enum obfuscation is enabled:
com/google/gwt/dom/client/DataTransfer.java:127
Looking at the DataTransfer source code, I can see that it has an enum DropEffect and the enum names are used in one of the methods (setDropEffect).
I'm using modern JsInterop-oriented GWT, so I'm not using this DataTransfer class (or anything in gwt-user.jar). It's annoying to have a useless warning. Is there an easy way to get rid of it?
I know how to exclude files in my own source folders.
Is it possible to exclude source folders from gwt-user? (Other than by physically deleting files from the jar!)
That looks like a bug - unfortunate too that the compiler doesn't remove this class. This should be easy to fix with a patch to GWT, adding a field to DropEffect for the name, since it must never be removed even when that compiler flag is enabled.
Is it possible to exclude source folders from gwt-user? (Other than by physically deleting files from the jar!)
What you must do is exclude the .gwt.xml file itself, by not inheriting it at all, even transitively. So, for example, if you do avoid all JSNI including Widget types in the User module, your .gwt.xml shouldn't reference the Dom module, or User, or anything else which references Dom. But once a module has been inherited, there is no way to "uninherit" it. And once a module is inherited, its sources are added, and cannot be un-added.

Using GWT's Pair in client code

I'm trying to use the class Pair from GWT:
com.google.gwt.dev.util.Pair
But I get the following error:
[ERROR] Line 126: No source code is available for type com.google.gwt.dev.util.Pair<L,R>; did you forget to inherit a required module?
In MyModule.gwt.xml I inherit the module com.google.gwt.user.User:
<inherits name="com.google.gwt.user.User" />
Which module do I need in order to use that class?
Code under the package com.google.gwt.dev only runs in the JVM.
If you want to reuse Pair, you have to copy it to a client side or shared namespace. But in this case you have to use different imports.
If you want to reuse it with the same namespace, you have to create your own .gwt.xml file that includes the com.google.gwt.dev namespace, but it is not an easy task since you might need a lot of exceptions in order to avoid other classes in this namespace using any kind of java code making gwt compiler fail.

Does GWT deferred binding return singletons of the same type within the scope of a single EntryPoint?

Let's say I have a number of GWT modules which are used as libraries, and one module with an entry point which inherits all of the library modules.
Each of the submodules needs to access a single instance of SomeClass.
If I call GWT.create(SomeClass.class) in modules A & B, do I get the same instance? If so, is this guaranteed?
No. GWT.create(SomeClass.class) compiles to new SomeClass(), unless there is a rebind rule of some kind - a replace-with or a generate-with rule will cause this to instead invoke the default constructor of whatever type is selected by those rules.
This means that GWT.create is not a suitable way to provide access to a singleton instance. Instead, consider some DI tool like Gin, or manual DI by always passing around the same instance. It is also possible to use the static keyword to keep a single instance where all code compiled into the same app can reference it.

Ignoring some elements/classes in JAXB binding

I use Hyperjaxb to generate some classes with JPA annotations from XML schemas. I'd like to specify which elements from given schema xjc should generate. I can't change xsd file. I can modify only bindings.xjb. I tried to use hj:ignored, but without success.
Well, hj:ignored is the answer. It allows you to make Hyperjaxb ignore certain classes.
Here's an example:
<jaxb:bindings
node="xsd:complexType[#name='issue121Type']//xsd:element[#name='simpleCollection']">
<hj:ignored/>
</jaxb:bindings>
Customizations work in schema as well as via xjb files.
See this project for instance.
How does "without success" reveal itself?

JAXB auto generated classes hierarchy

I'm generating java code based on various WSDL's. We have a different WSDL for every new version of the WebService that we release, each with its own namespace.
The thing is that normally the changes are minimal from one release to another, but I want to keep classes divided by namespace.
Is there a way to configure JAXB so that the auto generated classes implement a single interface/extend a single class, so I can refer to either of them without changing my code?
Dummy example:
WebService method: listScripts(ResultSize size);
Auto generated classes:
com.test.ws1.ResultSize
com.test.ws2.ResultSize
Both classes are exactly the same. Is there a way to arrange them in a class hierarchy so my code is isolated from changes in version numbers? i.e. a com.test.ResultSize interface implemented by both classes?
XJC has an extension for this purpose
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:superClass name="com.mycompany.xml.UserRootObject"/>
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
.
.
.
</xs:schema>
For more information see:
http://jaxb.java.net/nonav/2.0.2/docs/vendorCustomizations.html
The schema annotations can also be supplied via an external bindings file. For an example see:
How do you customize how JAXB generates plural method names?
It turned out that I can use a plugin provided in the JAXB2 Basics package:
Inheritance plugin
With this plugin I can specify different super classes for my generated ones, although I couldn't make the auto generated enums to implement a given interface.
To use it in Maven it was a pain (I'm generating classes from a WSDL, not using JAXB directly), so I switched to an external Ant task as specified in this blog