Community
Participate
Working Groups
The changes made to BinaryResourceImpl for GWT 2.7 need to be ported back to the core runtime. In general, we want to ensure that it's possible to exchange serializations between the standard runtime and the GWT runtime so we need to add various options and styles to support that. Of course we need to maintain backward compatibility with the older serialization format as we do this.
Created attachment 185812 [details] Patches to address the issue. This syncs the implementations back up. I think it makes sense for the GWT version to support different defaults, i.e., ones that work for GWT's client. I'm writing out a style int now, which breaks serialization for existing GWT serializations, but I think that would be best. I need to test it more before committing it. Thomas, could you try these out to see if they work well for you?
(In reply to comment #1) > ... Thomas, could you try these out to see if they work well for > you? I'd be happy to. Michal, what's the minimal releng setup needed in order to build emf.ecore.resource ?
I applied the patch in a GWT application and I am getting an ArrayIndexOutOfBoundsException (see the stack trace below); The problem is in an empty array being used in this method: public String convertEDateToString(EDataType eDataType, Object instanceValue) { if (instanceValue == null) { return null; } else { // THE "EDATE_FORMATS" IS EMPTY HERE -> array index out of bounds return EDATE_FORMATS[0].format((Date)instanceValue); } } The root cause of the problem is how the array is initialized on the server side: static { DateTimeFormat[] result; try { result= new DateTimeFormat[] { DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSSZ"), DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSS"), DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss"), DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm"), DateTimeFormat.getFormat("yyyy-MM-dd") }; } catch (Throwable exception) { // WE ARE ON THE SERVER, THAT'S WHY WE CAN'T USE GWT CLIENT CLASSES // AND THE CODE FALLS TO THIS EXCEPTION HANDLER ON CLASS INITIALIZATION result = new DateTimeFormat[0]; } // THIS ARRAY IS FINALLY EMPTY WHEN INITIALIZED ON THE SERVER EDATE_FORMATS = result; The stack trace: Thread [1371706360@qtp-950233939-0] (Suspended) EcoreFactoryImpl.convertEDateToString(EDataType, Object) line: 454 EcoreFactoryImpl.convertToString(EDataType, Object) line: 185 BinaryResourceImpl$EObjectOutputStream.saveFeatureValue(InternalEObject, int, BinaryResourceImpl$EObjectOutputStream$EStructuralFeatureData) line: 975 BinaryResourceImpl$EObjectOutputStream.saveEObject(InternalEObject, BinaryResourceImpl$EObjectOutputStream$Check) line: 845 BinaryResourceImpl$EObjectOutputStream.saveEObjects(InternalEList<InternalEObject>, Check) line: 651 BinaryResourceImpl$EObjectOutputStream.saveFeatureValue(InternalEObject, int, BinaryResourceImpl$EObjectOutputStream$EStructuralFeatureData) line: 896 BinaryResourceImpl$EObjectOutputStream.saveEObject(InternalEObject, BinaryResourceImpl$EObjectOutputStream$Check) line: 845 BinaryResourceImpl$EObjectOutputStream.saveFeatureValue(InternalEObject, int, BinaryResourceImpl$EObjectOutputStream$EStructuralFeatureData) line: 873 BinaryResourceImpl$EObjectOutputStream.saveEObject(InternalEObject, BinaryResourceImpl$EObjectOutputStream$Check) line: 845 BinaryResourceImpl$EObjectOutputStream.saveEObjects(InternalEList<InternalEObject>, Check) line: 651 BinaryResourceImpl$EObjectOutputStream.saveResource(Resource) line: 639 BinaryResourceImpl.doSave(OutputStream, Map<?,?>) line: 136 BinaryResourceImpl(ResourceImpl).save(OutputStream, Map<?,?>) line: 1249 BinaryResourceImpl(ResourceImpl).save(Map<?,?>, Callback<Resource>) line: 1026 BinaryResourceImpl(ResourceImpl).save(Map<?,?>) line: 972 LoginServiceImpl.login(String) line: 114 ...
Oh yeah, the lack of proper support for date formatting on the client and the server is a long standing problem. The support available on the client doesn't work on the server and the regular Java mechanism isn't supported on the client. So somehow I need to get the regular Java mechanism available on the server. I have some ideas for that. I'll work on a patch and include it here. Note that I removed the special support for date so it can be handled like any normal type but that means I have to solve this problem as part of making the serialization work for binary.
Created attachment 187256 [details] Patches to address the issue. With these changes, the client runtime will do what it did before and the server runtime will initialize the date formatting support used with the standard runtime. It's not been extensively tested...
It's better now - our GWT application works fine. However, when I try to load the resource saved by the GWT application in a non-GWT application, I get another error (although I applied the patches on both sides): java.lang.NegativeArraySizeException at com.cloudsmith.stack.resource.impl.BinaryResourceImpl$BinaryIO.allocateInternalEObjectArray(BinaryResourceImpl.java:116) at com.cloudsmith.stack.resource.impl.BinaryResourceImpl$EObjectInputStream.loadResource(BinaryResourceImpl.java:1035) at com.cloudsmith.stack.resource.impl.BinaryResourceImpl.doLoad(BinaryResourceImpl.java:72) at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1494) at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1282) at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoad(ResourceSetImpl.java:255) at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:270) at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:397)
Which options did you use? Be aware that the default for the standard runtime is the old version OPTION_VERSION: public static class BinaryIO { public enum Version { VERSION_1_0, /** * @since 2.7 */ VERSION_1_1 } The default for the GWT runtime is the new version (because it can't support some of the things in the older version). With the new version, a style word is written out so that on deserializing the same options are used as during serializing. This will cause the type of problem you report. Also, OPTION_STYLE_BINARY_FLOATING_POINT must be true for GWT; GWT doesn't support the binary encoding/decoding. OPTION_STYLE_BINARY_DATE would have solved the date issue you reported, but with this patch, the textual representation should work as well. And finally, OPTION_STYLE_PROXY_ATTRIBUTES is something you might want to use; it's up to you.
Created attachment 187410 [details] A serialized resource from GWT which can't be read by standard EMF.
I don't use any specific options. Although the data is not created in a browser but on the server, it still uses emf4gwt bundles. There bundles are patched with latest patches from this issue. When I read the stored data with a standard EMF application, I can see that the version retrieved from the serialized resource is really VERSION_1_1. Then, the style is read and its value is "-1". Is this expected? Finally, the size of the array is read and its value is "-1" as well. An attempt to allocated space for this array fails with java.lang.NegativeArraySizeException. What am I doing wrong? I am including an attachment containing the serialized resource.
Created attachment 187476 [details] Patches to address the issue. The problem is we were reading the style int using readCompressedInt but we wrote it with writeInt,not writeCompressedInt. I also fixed an issue with the defaulting of the style bit in the standard runtime; it should use binary for float by default (though GWT can't consume that).
The fixes have been committed to CVS for 2.7.
The changes are available in EMF 2.7 M7 or an earlier build.