GWT Hosted Mode RPC Serialization file with bad class definition causes IncompatibleRemoteServiceException - eclipse

I have a GWT project in Eclipse that throws a com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException when using hosted mode because the code server RPC file hashcode does not match the server RPC file hashcode.
I've tracked this down to a couple classes that implement com.extjs.gxt.ui.client.data.BeanModelTag. These classes appear to be included in the code server generated RPC file incorrectly. Additionally, the class names appear mangled.
For example, instead of com.acme.beans.MyBean the class is referenced as com.acme.beans.BeanModel_com_acme_beans_MyBean.
I suspect this has something to do with the class path for my debug target incorrectly including some jar, src dir, or other project incorrectly, but I don't have good feel for how to debug this further.

GXT 2 (current is 3, 4 should beta soonish) had a feature where it could generate BaseModelData types based on a java bean or pojo, allowing for reflection-like features that GXT 2 used to render templates and grid cells (GXT 3 has compile-time features that work out that property access instead). The BeanModels are not meant to be sent over the wire - instead, you should be sending your original MyBean over the wire.
This generated BeanModel instance is designed to wrap the original MyBean, and is only available to the client code. To pass back to the server again, unwrap the bean - use getBean() to get the underlying pojo.

Related

How to create a custom annotation processor for Eclipse

I'm trying to create a custom annotation processor that generates code at compilation time (as hibernate-jpamodelgen does). I've looked in the web, and I find custom annotation processors that works with maven, but do nothing when added to the Annotation Processing > Factory Path option. How could I create a processor compatible in this way? I have not found a tutorial that works.
My idea is to, for example, annotate an entity to generate automatically a base DTO, a base mapper, etc that can be extended to use in the final code.
Thank you all
OK, Already found out the problem. The tutorial I hda found out dint't specified that, in order to the compiler to be able to apply the annotation processor, there must be a META-INF/services/javax.annotation.processing.Processor file that contains the qualified class name of the processor (or processors).
I created the file pointing to my processor class, generated the jar and added it to Annotation Processing > Factory Path and all worked correctly.
Just be careful to keep the order of the processors correctly (for example, hibernate model generator claims the classes, so no more generation will be made after it), and change the jar file name each time you want to replace the library (it seems eclipse keeps a cache). These two things have given me a good headache.
Thanks all

GWT Pass Config Vars From Server to Client

On startup of my application i would like to make an rpc call form the client to the server. The call would result in the server creating a Properties object from a .properties file and passing it back to the client. However this does not seem to be possible as when i do this i get an error "No source code is available for type java.util.Properties; did you forget to inherit a required module?". I then tried to use a GWT Dictionary instead but doing so resulted in a error because a dictionary object is not serializable. Any ideas of how to fix either of the above 2 errors or of another way of doing this.
You cannot pass java.util.Properties back to client in RPC. The list of java classes in GWT that are emulated is listed http://www.gwtproject.org/doc/latest/RefJreEmulation.html
Also you should process the properties file into a model/pojo class in serializable java class and pass it back in RPC. You can use JSON object to do the same.
In any case you should process the properties file on server side into a format that is acceptable to GWT via JSON or RequestFactory or RPC.

GWT: How to serialize objects

I'd like to know if it is possible to use the serializer of GWT. When using the rpc-mechnism of GWT, GWT serializes the objects on the client and deserializes the objects on the server. For this mechanism you have to use special servlets (RemoteServiceServlet) of GWT. But i want to use the normal HttpServlets and therefore i have to serialize and deserialize the objects by myself.
All the code you need to look at is in the RemoteServiceServlet.java. Focus on the processCall method.
The RPC.decodeRequest(payload, ...) will give you a RPCRequest object which includes the method to be called and the deserialized parameters.
To encode the response focus on RPC.invokeAndEncodeResponse() and RPC.encodeResponseForSuccess() methods.
[EDITED]
In client-side it's worth to take a look to the proxy classes generated by the RPC generator, concretely the YourService_Proxy.java file. Generated files are left somewhere in your project's folder structure after compiling a project (you can indicate this folder with the -gen though).
The interesting code is in in the RemoteServiceProxy, looking at the createStreamWritter method, you can see how to serialize your objects. In the createStreamReader you can see how to deserialize a message from the server.
See gwt-byte-serializer
SerializerInt ser = new Serializer();
ser.writeValue("test");
ser.writeValue(new int[]{5,1,6});
String buffer = ser.getBuffer();
SerializerInt des = new Serializer(buffer);
des.readString()
des.readIntegerArr()

TrueZip 7 requires Java 7? NoClassDefFoundError: java/nio/file/Path on Java 6

TFile depends on java.nio.file.Path (toPath() method returns java.nio.file.Path) that isn't available on Java 6 so calling any TFile method on Java 6 throws "java.lang.NoClassDefFoundError: java/nio/file/Path"
How do you manage to use TFile on Java 6? What I'm thinking of is getting the sources, re-compiling them without this method and using a patched version which is kind of unpleasant solution.
No, TrueZIP 7 does not require JSE 7, JSE 6 is enough as the home page documents. However, some features are only available on JSE 7 (e.g. the TrueZIP Path module) and hence a run time test is performed.
With correct class loader implementations you will never see NoClassDefFoundError. However, some environments have broken class loader implementations which do eager class loading - despite the lazy class loading which is mandated by the spec. Only then you would get a NoClassDefFoundError.
On another note, please mind the Eclipse license of the project. If you really wanted to fix this by patching (you can't because there are circular dependencies between java.io.File and java.nio.file.Path which are the reason for this design), then you would have to publish this fork.
Appendix:
The Java Language Specification for Java 6, chapter 12.2.1 "The Loading Process" reads:
Different subclasses of ClassLoader may implement different loading policies. In particular, a class loader may cache binary representations of classes and interfaces, prefetch them based on expected usage, or load a group of related classes together. These activities may not be completely transparent to a running application if, for example, a newly compiled version of a class is not found because an older version is cached by a class loader. It is the responsibility of a class loader, however, to reflect loading errors only at points in the program where they could have arisen without prefetching or group loading.
English isn't my mother tongue, but I take it from the last sentence that eager class loading is OK as long as the class loader doesn't throw up just because an unused class failed to load eagerly. So if a class loader throws up because TFile.toPath() needs to return a java.nio.file.Path although you never call this method then I consider this to be a problem with the class loader. As an aside, TFile.toPath() throws an UnsupportedOperationException - please check the Javadoc for details.
I would have preferred to take another route but the circular dependency between java.io.File.toPath() and java.nio.file.Path.toFile() left me with no choice.

GWT and ReflectionToStringBuilder.toString()

I have a problem with the GWT compiler. When I add a next method to my entity class:
#Override
public String toString() {
return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
the compiler gave me next error:
ERROR: Deferred binding failed for 'com.mvp4g.client.Mvp4gModule'; expect subsequent failures
ERROR: Unable to load module entry point class plaut.wimc.avl.admin.client.Admin (see associated exception for details)
java.lang.RuntimeException: Deferred binding failed for 'com.mvp4g.client.Mvp4gModule' (did you forget to inherit a required module?)
When I remove it, all works fine. I don't understand why gave me compiler such error. This toString method is used in roo IDT's too and there is no such error.
All Java code used in the client side needs to be able to compile to JavaScript. ReflectionToStringBuilder uses reflection which isn't available in JavaScript so this method can't be used in your client side code.
This compile error refers to the fact that all Java code must be accessed by the GWT copmiler via path parameters in GWT module files and must be available in source format. In this case no GWT module file is present, hence the error, because the compiler can't find the sources for the ReflectionToStringBuilder method. Although you can create such a file for this specific case and add the sources, it won't work as reflection won't work.
Looks like the problem is with ReflectionToStringBuilder. Is it a GWT module? If yes, then it needs to be added an inherited module in your project's *.gwt.xml