You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geode.apache.org by Kirk Lund <kl...@apache.org> on 2016/09/20 18:53:19 UTC

Error loading cluster config serialized prior to repackage

If current develop attempts to read a cluster config that was persisted
prior to the repackage, our code now throws ClassNotFoundException. Turns
out Cluster Config is implemented by the
class org.apache.geode.management.internal.configuration.domain.Configuration
which is a DataSerializable. Unfortunately, a DataSerializableFixedID was
never added for this class, so the code resorts to using the fully
qualified class name.

While brainstorming possible workarounds, we noticed a jgroups related
method in DataSerializer called swizzleClassNameForRead which is called
from readObject(DataInput):

  /**
   * For backward compatibility we must swizzle the package of
   * some classes that had to be moved when GemFire was open-
   * sourced.  This preserves backward-compatibility.
   *
   * @param name the fully qualified class name
   * @return the name of the class in this implementation
   */
  private static String swizzleClassNameForRead(String name) {
    String oldPackage = "org.apache.org.jgroups.stack.tcpserver";
    String newPackage = "org.apache.geode.distributed.internal.tcpserver";
    String result = name;
    if (name.startsWith(oldPackage)) {
      result = newPackage + name.substring(oldPackage.length());
    }
    return result;
  }

The package in red above never existed. I now have two questions: a) did
the repackage break this so that JGroups now need two swizzles (one for the
jgroups upgrade and now a 2nd for the apache repackage)? b) can cluster
Configuration piggy back on this technique for handling the serialized
Configuration for cluster config?

1) jgroups upgrade
    String oldPackage = "com.gemstone.jgroups.stack.tcpserver";
    String newPackage = "org.apache.geode.distributed.internal.tcpserver";

2) apache repackage for jgroups
    String oldPackage = "com.gemstone.gemfire.distributed.internal.tcpserver
";
    String newPackage = "org.apache.geode.distributed.internal.tcpserver";

3) apache repackage for cluster config
    String oldPackage = "com.gemstone.gemfire.management.internal.
configuration.domain";
    String newPackage = "org.apache.geode.management.
internal.configuration.domain";

Can anyone else think of something similar that might be broken? We could
scan the source code for DataSerializables that don't have a
corresponding DataSerializableFixedID.
Should we also scan for Serializable classes and try to determine if they
might be similarly persisted in a way that might break a feature?

Is this the best way to handle this? Should we reorganize
swizzleClassNameForRead to be a series of registered DataSwizzlers?

Thanks,
Kirk

Re: Error loading cluster config serialized prior to repackage

Posted by Dan Smith <ds...@pivotal.io>.
I like your idea of having registered DataSwizzlers. Would registering a
DataSerializer for these classes work? It would be nice to just use the
extension mechanism that's already there.

-Dan

On Tue, Sep 20, 2016 at 1:29 PM, Bruce Schuchardt <bs...@pivotal.io>
wrote:

> The repackage broke those two methods.  The oldPackage needs to replace
> "org.apache" with "com.gemstone".  It allows interaction with a locator
> from WAN sites and clients running GemFire.
>
> I'll fix that problem.
>
>
> Le 9/20/2016 à 11:53 AM, Kirk Lund a écrit :
>
>> If current develop attempts to read a cluster config that was persisted
>> prior to the repackage, our code now throws ClassNotFoundException. Turns
>> out Cluster Config is implemented by the
>> class org.apache.geode.management.internal.configuration.domain.Co
>> nfiguration
>> which is a DataSerializable. Unfortunately, a DataSerializableFixedID was
>> never added for this class, so the code resorts to using the fully
>> qualified class name.
>>
>> While brainstorming possible workarounds, we noticed a jgroups related
>> method in DataSerializer called swizzleClassNameForRead which is called
>> from readObject(DataInput):
>>
>>    /**
>>     * For backward compatibility we must swizzle the package of
>>     * some classes that had to be moved when GemFire was open-
>>     * sourced.  This preserves backward-compatibility.
>>     *
>>     * @param name the fully qualified class name
>>     * @return the name of the class in this implementation
>>     */
>>    private static String swizzleClassNameForRead(String name) {
>>      String oldPackage = "org.apache.org.jgroups.stack.tcpserver";
>>      String newPackage = "org.apache.geode.distributed.
>> internal.tcpserver";
>>      String result = name;
>>      if (name.startsWith(oldPackage)) {
>>        result = newPackage + name.substring(oldPackage.length());
>>      }
>>      return result;
>>    }
>>
>> The package in red above never existed. I now have two questions: a) did
>> the repackage break this so that JGroups now need two swizzles (one for
>> the
>> jgroups upgrade and now a 2nd for the apache repackage)? b) can cluster
>> Configuration piggy back on this technique for handling the serialized
>> Configuration for cluster config?
>>
>> 1) jgroups upgrade
>>      String oldPackage = "com.gemstone.jgroups.stack.tcpserver";
>>      String newPackage = "org.apache.geode.distributed.
>> internal.tcpserver";
>>
>> 2) apache repackage for jgroups
>>      String oldPackage = "com.gemstone.gemfire.distribu
>> ted.internal.tcpserver
>> ";
>>      String newPackage = "org.apache.geode.distributed.
>> internal.tcpserver";
>>
>> 3) apache repackage for cluster config
>>      String oldPackage = "com.gemstone.gemfire.management.internal.
>> configuration.domain";
>>      String newPackage = "org.apache.geode.management.
>> internal.configuration.domain";
>>
>> Can anyone else think of something similar that might be broken? We could
>> scan the source code for DataSerializables that don't have a
>> corresponding DataSerializableFixedID.
>> Should we also scan for Serializable classes and try to determine if they
>> might be similarly persisted in a way that might break a feature?
>>
>> Is this the best way to handle this? Should we reorganize
>> swizzleClassNameForRead to be a series of registered DataSwizzlers?
>>
>> Thanks,
>> Kirk
>>
>>
>

Re: Error loading cluster config serialized prior to repackage

Posted by Bruce Schuchardt <bs...@pivotal.io>.
The repackage broke those two methods.  The oldPackage needs to replace 
"org.apache" with "com.gemstone".  It allows interaction with a locator 
from WAN sites and clients running GemFire.

I'll fix that problem.

Le 9/20/2016 � 11:53 AM, Kirk Lund a �crit :
> If current develop attempts to read a cluster config that was persisted
> prior to the repackage, our code now throws ClassNotFoundException. Turns
> out Cluster Config is implemented by the
> class org.apache.geode.management.internal.configuration.domain.Configuration
> which is a DataSerializable. Unfortunately, a DataSerializableFixedID was
> never added for this class, so the code resorts to using the fully
> qualified class name.
>
> While brainstorming possible workarounds, we noticed a jgroups related
> method in DataSerializer called swizzleClassNameForRead which is called
> from readObject(DataInput):
>
>    /**
>     * For backward compatibility we must swizzle the package of
>     * some classes that had to be moved when GemFire was open-
>     * sourced.  This preserves backward-compatibility.
>     *
>     * @param name the fully qualified class name
>     * @return the name of the class in this implementation
>     */
>    private static String swizzleClassNameForRead(String name) {
>      String oldPackage = "org.apache.org.jgroups.stack.tcpserver";
>      String newPackage = "org.apache.geode.distributed.internal.tcpserver";
>      String result = name;
>      if (name.startsWith(oldPackage)) {
>        result = newPackage + name.substring(oldPackage.length());
>      }
>      return result;
>    }
>
> The package in red above never existed. I now have two questions: a) did
> the repackage break this so that JGroups now need two swizzles (one for the
> jgroups upgrade and now a 2nd for the apache repackage)? b) can cluster
> Configuration piggy back on this technique for handling the serialized
> Configuration for cluster config?
>
> 1) jgroups upgrade
>      String oldPackage = "com.gemstone.jgroups.stack.tcpserver";
>      String newPackage = "org.apache.geode.distributed.internal.tcpserver";
>
> 2) apache repackage for jgroups
>      String oldPackage = "com.gemstone.gemfire.distributed.internal.tcpserver
> ";
>      String newPackage = "org.apache.geode.distributed.internal.tcpserver";
>
> 3) apache repackage for cluster config
>      String oldPackage = "com.gemstone.gemfire.management.internal.
> configuration.domain";
>      String newPackage = "org.apache.geode.management.
> internal.configuration.domain";
>
> Can anyone else think of something similar that might be broken? We could
> scan the source code for DataSerializables that don't have a
> corresponding DataSerializableFixedID.
> Should we also scan for Serializable classes and try to determine if they
> might be similarly persisted in a way that might break a feature?
>
> Is this the best way to handle this? Should we reorganize
> swizzleClassNameForRead to be a series of registered DataSwizzlers?
>
> Thanks,
> Kirk
>