it seems in the DataSnap XE 8 transfer of TList class crashed, the problem seems to be the new property "FListHelper: TListHelper"
it seems in the DataSnap XE 8 transfer of TList class crashed, the problem seems to be the new property "FListHelper: TListHelper"
anyone else noticed this?
anyone else noticed this?
The list helper is new code in XE8 - Generics.Collections had a lot of code rewritten and it special-cases a large number of things based on type and size of T. However, if it crashes, what crashes? What is T, and on what operation?
ReplyDeleteIt probably crashes because the doofus TJson implementation just serializes all fields.
ReplyDeleteThere you go: https://quality.embarcadero.com/browse/RSP-10342
ReplyDeleteDavid Millington a simple list TList and datasnap displays the error like "tkpointer is not currently supportet"
ReplyDeletesimply create a datasnap server, which returns a list and make the call from a client.
Stefan Glienke exactly the same error
ReplyDeleteStefan Glienke That Json serialization code should be incinerated and be properly done from the scratch.
ReplyDeleteDalija Prasnikar That bad, really?
ReplyDeleteBill Meyer Yep. And root of most problematic issues is it doesn't use published properties for serialization, but all fields class has (private, protected, you name it).
ReplyDeleteDalija Prasnikar I'd like to say "unbelievable", but sadly, it's not. Code review, anyone?
ReplyDeleteDalija Prasnikar Nice list. :( That's progress? I will cling to XE7 for dear life!
ReplyDeleteI think many of you are missing the point here. Expecting the framework to be able to read the programmers mind and serialize arbitrary complex types is simply unrealistic.
ReplyDeleteWhen you need to serialize create a type that is designed for, and supports serialization.
TList has never supported serialization. Go back to the original implementation and you see these members:
FItems: array of T;
FCount: Integer;
FComparer: IComparer;
FOnNotify: TCollectionNotifyEvent;
Only the first two can be serialized.
On the other hand, TArray can perfectly well be serialized.
David Heffernan serializing descendants lists of TList and TObjectList in XE7 version works perfectly, changes made to the XE8 version that made it stop working.
ReplyDeleteI had to downgrade my Delphi for XE7 version
David Heffernan 'I think many of you are missing the point here' - the point is surely that the JSON code itself purports to 'serialize arbitrary complex types'. Most of the responses to the OP (including yours) are agreed that it shouldn't, and that it would instead do better to require some sort of explicit compatibility.
ReplyDeleteDalija's suggestion that the stock JSON serialisation should have reused the DFM infrastructure sounds sensible to me - the latter may not be perfect, but it works, is quite flexible once you learn some technicalities, and has stood the test of time. It also isn't liable to break every time TList internals change...!
+Luiz No it doesn't. It cannot serialize those members that I pointed out. It also serialize values in the range Count to Capacity-1.
ReplyDeleteChris Rolliston I'm not sure that ObjectToJsonObject really purports to do that. Until XE8 this method was undocumented! Even in XE8 there is no mention of the pitfalls of expecting the method to magically transform any class into JSON, and then hope to be able to deserialize back to where you started. At least, if that is mentioned, I cannot see where.
ReplyDeleteUnfortunately many devs don't know any better, and with no documentation to warn them they hope for the unobtainable. Anyone who thinks that TList has ever been serializable to JSON using ObjectToJsonObject is mistaken.
Dalija's suggestion has its merits. It's not the way I would go though. How would only serializing published methods help with JSON arrays? What Delphi types would map to arrays. I don't think we want to be forced to publish TArray properties. Would we have to start using TCollection? Would we all have to use TList and not be allowed to use different containers?
I think the design of ObjectToJsonObject is perhaps tenable if it were documented. Documented that for complex types you need to use an intermediate simpler record that contained just the state that needed to be persisted, and any arrays as TArray. But there are surely better designs.
The real problem though is that complex objects cannot be serialized without the programmer providing more information that is needed for the class to work at runtime. So, Stefan's bug report doesn't seem valid to me. I don't think TList has ever been supported in the manner that his QP report expects.
David Heffernan The real problem here is that someone pushed Java way of serialization upon language and frameworks and customer code bases that is not suitable for that kind of serialization.
ReplyDeleteYou may not like "published" directive, but this is the way Delphi serialized things from the beginning. That should be starting point for any kind of serialization in Delphi, and if finer grained control over serialization is needed than customization has to be built on top of that base.
Pure attribute based serialization is extremely bad (in any language), because it creates strong dependency between classes that have to be serialized and serialization frameworks.
Currently available solution for error-less serialization with built in JSON serialization are:
1. Create duplicate classes and structures that can be serialized with current framework - quite unacceptable for large structures and complex classes.
2. Add serialization attributes in TList and other core classes that will prevent serializing all fields - unacceptable because it creates dependency upon JSON framework.
Such issue could be more easily solved in Java because it has "transient" keyword for marking fields that should not be serialized, but Delphi does not have such thing.
Since both above solutions are equally bad the only way out of this mess is to redesign broken serialization framework.
There are numerous 3rd party JSON frameworks out there that are doing much better job than built in one, and it is not mission impossible.
+Dalija We've got minor differences here. I doubt we are far apart really.
ReplyDeleteWhat we agree on is that it is unrealistic to expect the framework to read the devs mind.
David Heffernan I think we are very close. Of course, framework cannot read devs mind, you have to tell it what to do.
ReplyDeleteWhere we differ is "how" and "where". Ideally, good framework will let you configure in details, but also good framework will by default need as little intervention as possible.
... so why isn't the JSON logic based on an interface where a custom implementation can be supplied by the caller if they want? I see this so much throughout the Delphi libraries, they assume that their own way of doing things is the best way, and rarely let clients bring their own logic to the table when alternatives can be justified. (It's improving, albeit slowly. Might be more widespread if it functional expressions weren't so flipping verbose and lacking a few key things that would really make them powerful in Delphi.)
ReplyDeleteI am having the same problem , any solution?
ReplyDelete