[serialization-1.32.0] de-serializing newer versions that the application can deal with

We have system data written out to an XML archive and being de-serialized at application startup. One object type in the archive we written at version 1 by a newer version of the application. We then ran an older version of the software which only understood version 0 of the object. Does serialization not check the 'BOOST_CLASS_VERSION' of an object before attempting to de-serialize it? If not, how can we access the 'BOOST_CLASS_VERSION' in a serialization member function? I'm looking to do something like this: (this code is just written now so probably is incorrect but hopefully gives the idea). How do we check 'version_of_T' below which should correspond to the BOOST_CLASS_VERSION for T? I'd probably have this only check if the ArchiveT::is_loading::value is true as serializing doesn't matter. The issue at the moment is that an access violation is being thrown which definitely isn't a good idea. I'd like a 'newer object version' exception thrown instead which would enable us to give more useful error information to the user or our error log. Thanks Russell namespace serialization { template <typename T> void check_version(T* Object, unsigned int version)) { if (version_of_T > version) { throw newer_version_exception(); } } } class test { template <typename ArciveT> void serialize(ArchiveT& ar, unsigned int version) { serialization::check_version(this, version); } }; BOOST_CLASS_VERSION(test, 0x00);

On Thursday, June 15, 2006 at 09:56:00 (+0100) Russell Hind writes:
... One object type in the archive we written at version 1 by a newer version of the application. We then ran an older version of the software which only understood version 0 of the object.
Does serialization not check the 'BOOST_CLASS_VERSION' of an object before attempting to de-serialize it?
I think what you mean is: does boost serialization guard against forward incompatibility? It does not: that's your job. For any version of your code, if you want to guard against forward incompatibility, you simply need to do this: #define TEST_CURRENT_VERSION 3 // or, something more sophisticated .. class test { template <typename Archive> void serialize(Archive& ar, const unsigned int version) { // This code will refuse to try to load serialized archives >= 4 if (version > CURRENT_VERSION) { throw forward_incompatibility_error("..."); } } }; BOOST_CLASS_VERSION(test, TEST_CURRENT_VERSION); Of course, you could make an argument that boost should do this automatically.:-) Bill

Bill Lear wrote:
I think what you mean is: does boost serialization guard against forward incompatibility? It does not: that's your job. For any version of your code, if you want to guard against forward incompatibility, you simply need to do this:
Yes.
BOOST_CLASS_VERSION(test, TEST_CURRENT_VERSION);
Of course, you could make an argument that boost should do this automatically.:-)
I'm quite happy to do this if serialization doesn't. My question is that TEST_CURRENT_VERSION will then be declared in a header file as #define. I'd rather avoid that. So if I have BOOST_CLASS_VERSION(test, 0x01); How do I access the version of test? Cheers Russell

Russell Hind wrote:
We have system data written out to an XML archive and being de-serialized at application startup.
One object type in the archive we written at version 1 by a newer version of the application. We then ran an older version of the software which only understood version 0 of the object.
Does serialization not check the 'BOOST_CLASS_VERSION' of an object before attempting to de-serialize it?
If not, how can we access the 'BOOST_CLASS_VERSION' in a serialization member function? I'm looking to do something like this: (this code is just written now so probably is incorrect but hopefully gives the idea). How do we check 'version_of_T' below which should correspond to the BOOST_CLASS_VERSION for T?
boost::serialization::version<T>::value should contain the version of the type being used by program. If you want old programs to check for newer versions try void serialize(Archive &ar, T & t, const unsigned version){ if(version > boost::serialization::version<T>::value) throw exception(....) It never occured to me to build this into the serialization library itself, Now that it has been mentioned, it seems like a worthy idea. I'll consider it. Robert Ramey

Robert Ramey wrote:
It never occured to me to build this into the serialization library itself, Now that it has been mentioned, it seems like a worthy idea. I'll consider it.
The only issue with you doing this automatically is that if people decide to change a newer version of software to serialize as an older version, but can still handle loading in the newer versions written by the previous version of software. Although would that happen in practice? I'd just increment the object version again. Cheers for the pointer on getting the version. Thanks Russell
participants (3)
-
Bill Lear
-
Robert Ramey
-
Russell Hind