I found that the more than 60% of the javaScript code generated by GWT on my application is for RPC serializers.
Also I found that serializers are not shared between service interfaces, I mean if I have for example AccountDTO type referenced on 2 rpc service interfaces, I will get 2 serializer classes instead of 1 for the same type.
In Order to reduce the size of the compiled code I was thinking that maybe I could use Deferred Binding in order to do a replacement of all the services interfaces I have for one big interface. If that could be possible, maybe then GWTCompiler will produce only one AccountDTO serializer instead of 2.
I’m not sure this is a good idea or if there is a better solution for my problem.
What I was trying to implement was something like this:
// Define new interface that extends all service interfaces
public interface GenericService extends RemoteService,
AccountingService,
FinancialService,..., { }
public interface GenericServiceAsync extends AccountingServiceAsync,
FinancialServiceAsync, ..., { }
// At Application.gwt.xml do:
<module>
...
...
<replace-with class="com.arballon.gwt.core.client.GenericService">
<when-this-is class="com.arballon.gwt.core.client.AccountingService>
</replace-with>
<replace-with class="com.arballon.gwt.core.client.GenericService">
<when-this-is class="com.arballon.gwt.core.client.FinancialService>
</replace-with>
...
...
But at the moment I was receiving the error:
[ERROR] Errors in ‘file:/C:/Users/Daniel/EclipseWorkspace/ADK/src/com/arballon/gwt/core/client/FinancialService.java’
[ERROR] Line 31: Rebind result ‘com.arballon.gwt.core.client.GenericService’ could not be found
Any thoughts about the issue will be appreciated.
Regards
Daniel
GWT’s RPC generation code builds several classes to do its work as you’ve noted: a
*_FieldSerializerfor each type that goes over the wire, and a*_Proxyclass for the RemoteService async type. That proxy type requires a*_TypeSerializer, which is the root of your problem – for some reason, GWT wires up all of the serialization/deserialization methods in a string->js function map, probably to facilitate fast lookups – but this setup code comes at the cost of lines of code that need to be in the final build. A more optimized approach could have eachFieldSerializerhave a registration method where it adds its methods to the static map owned by the Proxy – this is plagued, however, but GWT’s optimization of attempting to not referenceinstantiate(),deserialize()andserialize()methods if it doesnt appear they will be called.Your issue stems from having many types that can be serialized, and from your having attempted to build out
RemoteServicetypes that each describe specific units of functionality, but re-use many model types. Admirable goal, especially as it will probably make your server-side code look nicer, but apparently GWT bites you for it.The solution I attempted to offer you on freenode (as niloc132) was to build a single large
RemoteServicetype, which you namedGeneralService, and a matchingGeneralServiceAsync, each extending all of the existing rpc service types. My first thought was to use a<replace-with>to tell the generator system that when you want each RemoteService type to replace it withGeneralService, but as Tahir points out, this doesn’t make sense – GWT doesn’t pass rebind results back into itself to keep doing lookups. Instead, I would suggest that when you want a service async type, do the following:The rebind result from
GeneralServicewill implementGeneralServiceAsync, which is itself assignable toAccountingServiceAsync. If memory serves, you said that you have static methods/fields that provide these services – change those sites to always create aGeneralServiceAsyncinstance. As long as you do not invokeGWT.createon anyRemoteServicesubtype butGeneralService, you will limit the number ofTypeSerializersto one.As a side note, the
RemoteServiceProxysubtypes are stateless, so ensuring that you create only one instance might make it easier to build consistently, but saves no runtime memory or time, as they are almost certainly compiled out to static methods. The*_TypeSerializerclasses do have state however, but there is only one instance of each, so combining all of yourRemoteServices might save a very small amount of working memory.