1 2 Previous Next 19 Replies Latest reply on Dec 14, 2012 12:59 AM by gaohoward

    Solving the backward compatibility issue -- working with clients of old versions

    gaohoward

      The issue is that since 2.3 we have made changes to DiscoveryGroupConfiguration to support JGroups. This causes a serialization problem when a version 2.2 JMS client need to get a ConnectionFactory via JNDI from the new 2.3 server. The reason is that we have introduced some new class (BroadcastEndpointFactoryConfiguration) into DiscoveryGroupConfiguration. When a new CF is marshalled to version 2.2 client, it has problem de-serializing it because this new class cannot be found in its jars.

       

      To solve the problem we have to deliver a compatible DiscoveryGroupConfiguration object to 2.2 clients. To achieve this we

       

      1. add a new attribute named 'client-version' to the Connection Factory configuration. The value of the client version is a version string indicating which version of clients a connection factory is going to support. Valid values are '2.2' and '2.3'. Default is '2.3'. So if working with 2.2 clients, one should configure the CF like the following example:

       

         <connection-factory name="NettyConnectionFactory">

            <xa>false</xa>

            <discovery-group-ref discovery-group-name="dg-group1"/>

            <entries>

               <entry name="/ConnectionFactory"/>

            </entries>

            <client-version>2.2</client-version>

         </connection-factory>

       

      2. Rename DiscoveryGroupConfigutration class to DisoveryGroupConfigurationV2_3 and make the DiscoveryGroupConfiguration class to be a copy of version 2.2's. Then add a writeReplace() method to control the serialization of DiscoveryGroupConfigurationV2_3. If the CF is serialized for a 2.2 client, we use the writeReplace method to actually serialize a version 2.2 DiscoveryGroupConfiguration object. If it is for a 2.3 client, the DiscoveryGroupConfigurationV2_3 is serialized instead.

       

      3. A minor issue is in version 2.2 ServerLocator the initialConnectors can be null but in 2.3 it is always not null. This can cause a 2.2 client to malfunction. We have to add a writeObject() method to the ServerLocator to covert an empty initialConnectors array to null before it is seralized for 2.2 client.

       

      4. In case of AS7 integration, we add the same attribute to jms connection factory and pooled conection factory configurations. It will eventually be passed into hornetq core and the rest are all the same with standalone hornetq.

        • 1. Re: Solving the backward compatibility issue -- working with clients of old versions
          jbertram

          I assume that adding this new parameter is the least invasive way to solve the compatibility problem.  I don't know enough about the underlying issue to say otherwise.

           

          Thinking about usability here...

           

          1. Why not make the default <client-version> 2.2 for now?  It seems like that would cause the least head-aches for users upgrading.  Any user who wants to leverage the new JGroups discovery functionality can set the <client-version> to 2.3.  Maybe when 3.0 comes out we can change the default <client-version> to 2.3.
          2. Also, if this is just about JGroups (and not about an overall strategy to deal with version conflicts) then why not call the property something like <enable-jgroups-discovery> so that it's more clear?
          • 2. Re: Solving the backward compatibility issue -- working with clients of old versions
            gaohoward
            1. Why not make the default <client-version> 2.2 for now?  It seems like that would cause the least head-aches for users upgrading.  Any user who wants to leverage the new JGroups discovery functionality can set the <client-version> to 2.3.  Maybe when 3.0 comes out we can change the default <client-version> to 2.3.

            By default being 2.2 sure would be benefiting existing users to upgrade. Only new users or existing users who want to update their client jars and who want to use jgroups broadcasting will have to add this flag (also we need to update out jgroups example). The problem is that for each new version release (e.g. 3.0) this has to be done for those users.

             

             


            1. Also, if this is just about JGroups (and not about an overall strategy to deal with version conflicts) then why not call the property something like <enable-jgroups-discovery> so that it's more clear?

            This should be the overall strategy. It just happens we only found that the issue is caused by code changes involving mostly JGroups (or 'pluggable broadcasting mechanism' for that matter) support. And it does include fixing a 'null' problem which is not related to jgroups.

            • 3. Re: Solving the backward compatibility issue -- working with clients of old versions
              clebert.suconic

              Wouldn't that work if you only had DiscoveryGroupConfigurationV2_2? I mean.. 2_3 would be the class itself, and we would only move to a previous version if the version flag is set.

               

              The best option though would be: if JGroups is not being used... then WriteReplace will automatically replace it the 2.2. On that case we won't need the version attribute at all

              • 4. Re: Solving the backward compatibility issue -- working with clients of old versions
                gaohoward

                Clebert Suconic wrote:

                 

                Wouldn't that work if you only had DiscoveryGroupConfigurationV2_2? I mean.. 2_3 would be the class itself, and we would only move to a previous version if the version flag is set.

                 

                Haven't try that but I don't think this works. At client side when the CF is deserialized it would be looking for DiscoveryGroupConfigurationV2_2, which is not in the 2.2 client jars.

                 

                Clebert Suconic wrote:

                 

                The best option though would be: if JGroups is not being used... then WriteReplace will automatically replace it the 2.2. On that case we won't need the version attribute at all

                That may work if only JGroups is the reason. There is another one need to be addressed which is the 'null' issue I said before.  Client 2.2 depends on 'null' value of the connector array but new Client 2.3 depends on the 'zero length' of it to make right decision whether or not it should wait for initial broadcasting.

                • 5. Re: Solving the backward compatibility issue -- working with clients of old versions
                  gaohoward

                  I just found that AS7 uses slight different way to bind an object to JNDI (AS7BindingRegistry), it somehow didn't call writeReplace() method as I tested. I'm investigating it for the moment. If anybody have a good idea that'll be helpful.

                  • 6. Re: Solving the backward compatibility issue -- working with clients of old versions
                    gaohoward

                    Correction: I do see writeReplace() is called but the client still got CNF exception (looking for V2_3 class).

                    • 7. Re: Solving the backward compatibility issue -- working with clients of old versions
                      jmesnil

                      Justin Bertram wrote:

                       

                      I assume that adding this new parameter is the least invasive way to solve the compatibility problem.  I don't know enough about the underlying issue to say otherwise.

                       

                      Thinking about usability here...

                       

                      1. Why not make the default <client-version> 2.2 for now?  It seems like that would cause the least head-aches for users upgrading.  Any user who wants to leverage the new JGroups discovery functionality can set the <client-version> to 2.3.  Maybe when 3.0 comes out we can change the default <client-version> to 2.3.

                      For AS7, I think will set the default to 2.2 to preserve compatibility. Only if users requires jgroups should they move to client-version 2.3

                      • 8. Re: Solving the backward compatibility issue -- working with clients of old versions
                        ataylor

                        Correction: I do see writeReplace() is called but the client still got CNF exception (looking for V2_3 class).

                        Looks like the serialisation with these client libs works differently, when i tried with HQ standalone this worked but with these it seems to always write info on the new dg2_3 no matter what.

                         

                        Howard, can you try the following, change server locator to use the old clas but add a transient field that holds the newer version, this means old clients should work fine. Then override the writeObject/readobject and write the new version after the default write, so something like:

                         

                        writeObject(out)

                        {

                             out.defaultWriteObject()

                             if(v2_3)

                             {

                                  out.write(discoveryGroupConfigurationv2_3)

                             }

                        }

                         

                        let me know how that goes.

                         

                         

                        If any one has an alternative approach please jump in

                        • 9. Re: Solving the backward compatibility issue -- working with clients of old versions
                          ataylor

                          i forgot you can then access the newer version from inside serverlocator by DiscoveryGroupConfiguration.getV2_3 or something

                          • 10. Re: Solving the backward compatibility issue -- working with clients of old versions
                            clebert.suconic

                            I thought the replace would just replace the inside of the object.

                             

                             

                            Maybe we should take a step back on this... keep the DiscoveryGroupConfiguration as it was before... and add a new field such as jgroupsDiscoveryConfiguration and leave the one the way it is.

                             

                            if you use the new JGroups it will not be compatible with old clients.. as expected.. if you don't.. the field will be null and the client will probably just ignore it? (at least I hope so).

                            • 11. Re: Solving the backward compatibility issue -- working with clients of old versions
                              ataylor

                              I thought the replace would just replace the inside of the object.

                              It should do and does with the JDK default serialization.

                               

                              Maybe we should take a step back on this... keep the DiscoveryGroupConfiguration as it was before... and add a new field such as jgroupsDiscoveryConfiguration and leave the one the way it is.

                               

                              if you use the new JGroups it will not be compatible with old clients.. as expected.. if you don't.. the field will be null and the client will probably just ignore it? (at least I hope so).

                              I have a plan to do something like this tomorrow, will update on here when done, got some magic i think i can do.

                              • 12. Re: Solving the backward compatibility issue -- working with clients of old versions
                                gaohoward

                                Andy,

                                 

                                I don't think we can change DiscoveryGroupConfiguration.writeObject()/.readObject(), this means we have to update the client side jars. But I'm not sure about how the serialization really does about it. I'll try this anyway.

                                 

                                Thanks,

                                Howard

                                • 13. Re: Solving the backward compatibility issue -- working with clients of old versions
                                  gaohoward

                                  Forget it. I just realized the old client jar doesn't need to change.

                                  • 14. Re: Solving the backward compatibility issue -- working with clients of old versions
                                    gaohoward

                                    Good news is that it works. However got another class problem:

                                     

                                    Caused by: java.lang.ClassNotFoundException: org.hornetq.utils.Pair

                                     

                                    I checked the class has a different package in 2.2. Strange thou I didn't have this problem with standalone hornetq server.

                                     

                                    Howard

                                    1 2 Previous Next