提问者:小点点

Pivotal GemFire:Spring Data GemFire中的PDX序列化程序配置


我创建了一个具有2个定位器、2个缓存服务器和一个“客户”REPLICATE区域的GemFire集群。(域对象类在服务器启动期间放置在类路径中)。

我能够运行一个Java程序(对等)来加载集群中的“客户”区域。现在我们想移动到Spring Data GemFire,在那里我不确定如何配置PDX序列化和获取…

com.gemstone.gemfire.InternalGemFireException: java.io.NotSerializableException: com.gemfire.poc.DomainObjects.Customer

cache. xml在简单的Java程序中…

<?xml version="1.0" encoding="UTF-8"?><cache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schema.pivotal.io/gemfire/cache" xsi:schemaLocation="http://schema.pivotal.io/gemfire/cache http://schema.pivotal.io/gemfire/cache/cache-8.1.xsd" version="8.1" lock-lease="120" lock-timeout="60" search-timeout="300" is-server="false" copy-on-read="false">
 <pdx>
    <pdx-serializer>
      <class-name>
       com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer
      </class-name>
    <parameter name="classes">
      <string>com.gemfire.poc.DomainObjects.*</string>
    </parameter>
  </pdx-serializer>
 </pdx>
    <region name="Customer" refid="REPLICATE">
    <region-attributes refid="REPLICATE" scope="distributed-no-ack"> 
     <cache-loader>
        <class-name>com.citigroup.pulse.pt.gemfire.poc.clientserver.SimpleCacheLoader</class-name>
    </cache-loader>
</region-attributes>
    </region>
</cache>

Spring Boot应用程序中的spring-context. xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:gfe="http://www.springframework.org/schema/gemfire"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
                http://www.springframework.org/schema/data/gemfire 
                           http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd">

    <util:properties id="gemfireProperties">
        <prop key="log-level">config</prop>
        <prop key="locators">hostA[10334],hostB[10334]</prop>
    </util:properties>


    <bean id="mappingPdxSerializer" class="com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer"/>

    <gfe:cache use-bean-factory-locator="false" properties-ref="gemfireProperties" use-cluster-configuration="true" pdx-serializer-ref="mappingPdxSerializer" />

    <gfe:replicated-region id="Customer" ignore-if-exists="true">       
    </gfe:replicated-region>


</beans>

有人能帮我解决序列化问题吗?

Caused by: com.gemstone.gemfire.InternalGemFireException: java.io.NotSerializableException: com.gemfire.poc.DomainObjects.Customer
    at com.gemstone.gemfire.distributed.internal.DistributionManager.putOutgoing(DistributionManager.java:1954)
    at com.gemstone.gemfire.internal.cache.DistributedCacheOperation.distribute(DistributedCacheOperation.java:476)
    at com.gemstone.gemfire.internal.cache.AbstractUpdateOperation.distribute(AbstractUpdateOperation.java:65)
    at com.gemstone.gemfire.internal.cache.DistributedRegion.distributeUpdate(DistributedRegion.java:519)
    at com.gemstone.gemfire.internal.cache.DistributedRegion.basicPutPart3(DistributedRegion.java:500)
    at com.gemstone.gemfire.internal.cache.AbstractRegionMap.basicPut(AbstractRegionMap.java:3052)
    at com.gemstone.gemfire.internal.cache.LocalRegion.virtualPut(LocalRegion.java:5838)

确切地说,如何在spring-data-gemfire标签中添加ReflsionBasedAutoSerializer的“类”参数?

从Region检索值时的PDX反序列化异常:

com.gemstone.gemfire.ToDataException: PdxSerializer failed when calling toData on class javax.management.Notification
    at com.gemstone.gemfire.internal.InternalDataSerializer.writePdx(InternalDataSerializer.java:3130)
    at com.gemstone.gemfire.internal.InternalDataSerializer.writeUserObject(InternalDataSerializer.java:1520)
    at com.gemstone.gemfire.internal.InternalDataSerializer.writeWellKnownObject(InternalDataSerializer.java:1416)
    at com.gemstone.gemfire.internal.InternalDataSerializer.basicWriteObject(InternalDataSerializer.java:2208)
    at com.gemstone.gemfire.DataSerializer.writeObject(DataSerializer.java:3181)
    at com.gemstone.gemfire.internal.util.BlobHelper.serializeToBlob(BlobHelper.java:50)
    at com.gemstone.gemfire.internal.util.BlobHelper.serializeToBlob(BlobHelper.java:38)
    at com.gemstone.gemfire.internal.cache.UpdateOperation$UpdateMessage.toData(UpdateOperation.java:492)
    at com.gemstone.gemfire.internal.InternalDataSerializer.invokeToData(InternalDataSerializer.java:2407)
    at com.gemstone.gemfire.internal.InternalDataSerializer.writeDSFID(InternalDataSerializer.java:1378)
    at com.gemstone.gemfire.internal.tcp.MsgStreamer.writeMessage(MsgStreamer.java:239)
    at com.gemstone.gemfire.distributed.internal.direct.DirectChannel.sendToMany(DirectChannel.java:458)
    at com.gemstone.gemfire.distributed.internal.direct.DirectChannel.sendToOne(DirectChannel.java:310)
    at com.gemstone.gemfire.distributed.internal.direct.DirectChannel.send(DirectChannel.java:696)
    at com.gemstone.gemfire.distributed.internal.membership.jgroup.JGroupMembershipManager.directChannelSend(JGroupMembershipManager.java:2929)
    at com.gemstone.gemfire.distributed.internal.membership.jgroup.JGroupMembershipManager.send(JGroupMembershipManager.java:3163)
    at com.gemstone.gemfire.distributed.internal.DistributionChannel.send(DistributionChannel.java:79)
    at com.gemstone.gemfire.distributed.internal.DistributionManager.sendOutgoing(DistributionManager.java:3907)
    at com.gemstone.gemfire.distributed.internal.DistributionManager.sendMessage(DistributionManager.java:3948)
    at com.gemstone.gemfire.distributed.internal.DistributionManager.putOutgoing(DistributionManager.java:1951)
    at com.gemstone.gemfire.internal.cache.DistributedCacheOperation.distribute(DistributedCacheOperation.java:476)
    at com.gemstone.gemfire.internal.cache.AbstractUpdateOperation.distribute(AbstractUpdateOperation.java:65)
    at com.gemstone.gemfire.internal.cache.DistributedRegion.distributeUpdate(DistributedRegion.java:519)
    at com.gemstone.gemfire.internal.cache.DistributedRegion.basicPutPart3(DistributedRegion.java:500)
    at com.gemstone.gemfire.internal.cache.ProxyRegionMap.basicPut(ProxyRegionMap.java:242)
    at com.gemstone.gemfire.internal.cache.LocalRegion.virtualPut(LocalRegion.java:5838)
    at com.gemstone.gemfire.internal.cache.DistributedRegion.virtualPut(DistributedRegion.java:387)
    at com.gemstone.gemfire.internal.cache.LocalRegionDataView.putEntry(LocalRegionDataView.java:118)
    at com.gemstone.gemfire.internal.cache.LocalRegion.basicPut(LocalRegion.java:5228)
    at com.gemstone.gemfire.internal.cache.LocalRegion.validatedPut(LocalRegion.java:1599)
    at com.gemstone.gemfire.internal.cache.LocalRegion.put(LocalRegion.java:1582)
    at com.gemstone.gemfire.internal.cache.AbstractRegion.put(AbstractRegion.java:327)
    at com.gemstone.gemfire.management.internal.ManagementResourceRepo.putEntryInLocalNotificationRegion(ManagementResourceRepo.java:169)
    at com.gemstone.gemfire.management.internal.NotificationHub$NotificationHubListener.handleNotification(NotificationHub.java:193)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor$ListenerWrapper.handleNotification(DefaultMBeanServerInterceptor.java:1754)
    at javax.management.NotificationBroadcasterSupport.handleNotification(NotificationBroadcasterSupport.java:275)
    at javax.management.NotificationBroadcasterSupport$SendNotifJob.run(NotificationBroadcasterSupport.java:352)
    at javax.management.NotificationBroadcasterSupport$1.execute(NotificationBroadcasterSupport.java:337)
    at javax.management.NotificationBroadcasterSupport.sendNotification(NotificationBroadcasterSupport.java:248)
    at com.gemstone.gemfire.management.internal.beans.ManagementAdapter.handleRegionRemoval(ManagementAdapter.java:879)
    at com.gemstone.gemfire.management.internal.beans.ManagementListener.handleEvent(ManagementListener.java:123)
    at com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.notifyResourceEventListeners(InternalDistributedSystem.java:2252)
    at com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.handleResourceEvent(InternalDistributedSystem.java:506)
    at com.gemstone.gemfire.internal.cache.LocalRegion.basicDestroyRegion(LocalRegion.java:6642)
    at com.gemstone.gemfire.internal.cache.DistributedRegion.basicDestroyRegion(DistributedRegion.java:1957)
    at com.gemstone.gemfire.internal.cache.LocalRegion.close(LocalRegion.java:2219)
    at org.springframework.data.gemfire.RegionFactoryBean.destroy(RegionFactoryBean.java:529)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:272)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.destroySingletons(FactoryBeanRegistrySupport.java:230)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968)
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1032)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1008)
    at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:929)
Caused by: org.springframework.data.mapping.model.MappingException: Could not write value for property protected transient java.lang.Object java.util.EventObject.source
    at org.springframework.data.gemfire.mapping.MappingPdxSerializer$2.doWithPersistentProperty(MappingPdxSerializer.java:188)
    at org.springframework.data.gemfire.mapping.MappingPdxSerializer$2.doWithPersistentProperty(MappingPdxSerializer.java:173)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:309)
    at org.springframework.data.gemfire.mapping.MappingPdxSerializer.toData(MappingPdxSerializer.java:173)
    at com.gemstone.gemfire.internal.InternalDataSerializer.writePdx(InternalDataSerializer.java:3075)
    ... 56 more
Caused by: com.gemstone.gemfire.pdx.PdxFieldAlreadyExistsException: The field "source" already exists.
    at com.gemstone.gemfire.pdx.internal.PdxType.addField(PdxType.java:262)
    at com.gemstone.gemfire.pdx.internal.PdxWriterImpl.updateMetaData(PdxWriterImpl.java:858)
    at com.gemstone.gemfire.pdx.internal.PdxWriterImpl.updateMetaData(PdxWriterImpl.java:851)
    at com.gemstone.gemfire.pdx.internal.PdxWriterImpl.writeObject(PdxWriterImpl.java:303)
    at com.gemstone.gemfire.pdx.internal.PdxWriterImpl.writeField(PdxWriterImpl.java:705)
    at com.gemstone.gemfire.pdx.internal.PdxWriterImpl.writeField(PdxWriterImpl.java:625)
    at org.springframework.data.gemfire.mapping.MappingPdxSerializer$2.doWithPersistentProperty(MappingPdxSerializer.java:184)
    ... 60 more

共1个答案

匿名用户

你在这里有几个选择,以及一些建议。

1)首先,我不会使用Pivotal GemFire的o. a.g.pdx.反射BasedAutoSerializer。相反,SDG有一个基于Spring Data的映射基础设施(即o.s.d.g.map.MappingPdxSerializer)的更健壮的PdxSerializer实现。

此外,SDG的MappingPdxSerializer允许您在实体字段/属性的基础上逐个注册自定义PdxSerializer的。想象一下,如果您的客户类引用了一个复杂的地址类,并且该类具有特殊的序列化需求。

此外,SDG的MappingPdxSerializer可以处理瞬态和只读属性。

最后,您不必弄乱任何繁琐/复杂的正则表达式来正确识别需要序列化的应用程序域模型类型。

2)其次,您可以利用Spring的JavaConfig以及SDG新的基于注释的配置模型来配置Pivotal GemFire PDX序列化,就像这样简单……

@SpringBootApplication
@PeerCacheApplication
@EnablePdx(..)
class MySpringBootApacheGeodeApplication {
  ...
}

也就是说,使用SDG@EnablePdx注释。

有关上述#1和#2的更多详细信息,请参见此处和此处。

当然,后者更适用于将Pivotal GemFire 9. x与Spring Data GemFire Kay(2.0)一起使用。从您的XML配置中的com.gemstone.gemfire.pdx.RefltionBasedAutoSerializer中的包(即com.gemstone.gemfire包)判断,您是否正在使用Pivotal GemFire 8.2.x与Spring Data GemFire Ingalls(或1.9.x.RELEASE),也许?

但是,如果您坚持或被要求使用XML进行配置,那么您可以执行以下操作…

<beans ...>

  <bean id="mappingPdxSerializer" class="org.springframework.data.gemfire.mapping.MappingPdxSerializer"/>

  <gfe:cache pdx-serializer-ref="mappingPdxSerializer" .../>

</beans>

而且,如果您真的想使用Pivotal GemFire的ReflectBasedAutoSerializer,那么您可以在SDG测试套件中找到它的使用示例。例如。

在我的spring-gemfire测试项目/repo中,我还有一些例子(这是一个相当混乱的项目,作为警告,我不再维护这个repo了)。这里的例子,在GemFire的API中使用Java配置,这里,这里也显示了SDG的MappingPdxSerializer的使用(相比之下),等等。许多例子在我的存储库中都是谜语。

希望这有帮助!

干杯,-约翰